diff --git a/.drone.yml b/.drone.yml index 03a83c070fea1..3d9a62ee73df7 100644 --- a/.drone.yml +++ b/.drone.yml @@ -153,7 +153,7 @@ services: MYSQL_DATABASE: test - name: mysql8 - image: mysql:8.0 + image: mysql:8 environment: MYSQL_ALLOW_EMPTY_PASSWORD: yes MYSQL_DATABASE: testgitea @@ -319,7 +319,7 @@ trigger: services: - name: pgsql pull: default - image: postgres:9.5 + image: postgres:10 environment: POSTGRES_DB: test POSTGRES_PASSWORD: postgres @@ -503,7 +503,7 @@ steps: pull: always image: techknowlogick/xgo:go-1.16.x commands: - - curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt-get install -y nodejs + - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs - export PATH=$PATH:$GOPATH/bin - make release environment: @@ -599,7 +599,7 @@ steps: pull: always image: techknowlogick/xgo:go-1.16.x commands: - - curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt-get install -y nodejs + - curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs - export PATH=$PATH:$GOPATH/bin - make release environment: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 702062490db8b..9f5ecab4b060f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,6 @@ Please check the following: -1. Make sure you are targeting the `master` branch, pull requests on release branches are only allowed for bug fixes. +1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for bug fixes. 2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/master/CONTRIBUTING.md 3. Describe what your pull request does and which issue you're targeting (if any) diff --git a/Dockerfile.rootless b/Dockerfile.rootless index a379babc2d9a7..6f4e704f00726 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -35,6 +35,7 @@ RUN apk --no-cache add \ ca-certificates \ gettext \ git \ + curl \ gnupg RUN addgroup \ diff --git a/cmd/serv.go b/cmd/serv.go index 56167f63a8781..1c9f5dc44e9d3 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -81,6 +81,10 @@ func fail(userMessage, logMessage string, args ...interface{}) { } } + if len(logMessage) > 0 { + _ = private.SSHLog(true, fmt.Sprintf(logMessage+": ", args...)) + } + os.Exit(1) } diff --git a/contrib/systemd/gitea.service b/contrib/systemd/gitea.service index ac6a13ec573e7..d6a4377ec8091 100644 --- a/contrib/systemd/gitea.service +++ b/contrib/systemd/gitea.service @@ -3,14 +3,23 @@ Description=Gitea (Git with a cup of tea) After=syslog.target After=network.target ### -# Don't forget to add the database service requirements +# Don't forget to add the database service dependencies ### # -#Requires=mysql.service -#Requires=mariadb.service -#Requires=postgresql.service -#Requires=memcached.service -#Requires=redis.service +#Wants=mysql.service +#After=mysql.service +# +#Wants=mariadb.service +#After=mariadb.service +# +#Wants=postgresql.service +#After=postgresql.service +# +#Wants=memcached.service +#After=memcached.service +# +#Wants=redis.service +#After=redis.service # ### # If using socket activation for main http/s diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index b1fe95e6e2096..f37157c3b10e1 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -444,6 +444,11 @@ ROUTER = console ;ACCESS_LOG_TEMPLATE = {{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}" ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; SSH log (Creates log from ssh git request) +;; +;ENABLE_SSH_LOG = false +;; ;; Other Settings ;; ;; Print Stacktraces with logs. (Rarely helpful.) Either "Trace", "Debug", "Info", "Warn", "Error", "Critical", default is "None" diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 9bb790f4c9c93..ee701b6572482 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -657,6 +657,7 @@ Default templates for project boards: - `ROUTER`: **console**: The mode or name of the log the router should log to. (If you set this to `,` it will log to default gitea logger.) NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take effect. Configure each mode in per mode log subsections `\[log.modename.router\]`. - `ENABLE_ACCESS_LOG`: **false**: Creates an access.log in NCSA common log format, or as per the following template +- `ENABLE_SSH_LOG`: **false**: save ssh log to log file - `ACCESS`: **file**: Logging mode for the access logger, use a comma to separate values. Configure each mode in per mode log subsections `\[log.modename.access\]`. By default the file mode will log to `$ROOT_PATH/access.log`. (If you set this to `,` it will log to the default gitea logger.) - `ACCESS_LOG_TEMPLATE`: **`{{.Ctx.RemoteAddr}} - {{.Identity}} {{.Start.Format "[02/Jan/2006:15:04:05 -0700]" }} "{{.Ctx.Req.Method}} {{.Ctx.Req.URL.RequestURI}} {{.Ctx.Req.Proto}}" {{.ResponseWriter.Status}} {{.ResponseWriter.Size}} "{{.Ctx.Req.Referer}}\" \"{{.Ctx.Req.UserAgent}}"`**: Sets the template used to create the access log. - The following variables are available: diff --git a/docs/content/doc/developers/api-usage.en-us.md b/docs/content/doc/developers/api-usage.en-us.md index 15fedbe2c164d..06cbc9b72e1e1 100644 --- a/docs/content/doc/developers/api-usage.en-us.md +++ b/docs/content/doc/developers/api-usage.en-us.md @@ -40,8 +40,42 @@ better understand this by looking at the code -- as of this writing, Gitea parses queries and headers to find the token in [modules/auth/auth.go](https://github.com/go-gitea/gitea/blob/6efdcaed86565c91a3dc77631372a9cc45a58e89/modules/auth/auth.go#L47). -You can create an API key token via your Gitea installation's web interface: -`Settings | Applications | Generate New Token`. +## Generating and listing API tokens + +A new token can be generated with a `POST` request to +`/users/:name/tokens`. + +Note that `/users/:name/tokens` is a special endpoint and requires you +to authenticate using `BasicAuth` and a password, as follows: + + +```sh +$ curl -XPOST -H "Content-Type: application/json" -k -d '{"name":"test"}' -u username:password https://gitea.your.host/api/v1/users//tokens +{"id":1,"name":"test","sha1":"9fcb1158165773dd010fca5f0cf7174316c3e37d","token_last_eight":"16c3e37d"} +``` + +The ``sha1`` (the token) is only returned once and is not stored in +plain-text. It will not be displayed when listing tokens with a `GET` +request; e.g. + +```sh +$ curl --request GET --url https://yourusername:password@gitea.your.host/api/v1/users//tokens +[{"name":"test","sha1":"","token_last_eight:"........":},{"name":"dev","sha1":"","token_last_eight":"........"}] +``` + +To use the API with basic authentication with two factor authentication +enabled, you'll need to send an additional header that contains the one +time password (6 digitrotating token). +An example of the header is `X-Gitea-OTP: 123456` where `123456` +is where you'd place the code from your authenticator. +Here is how the request would look like in curl: + +```sh +$ curl -H "X-Gitea-OTP: 123456" --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens +``` + +You can also create an API key token via your Gitea installation's web +interface: `Settings | Applications | Generate New Token`. ## OAuth2 Provider @@ -82,26 +116,6 @@ or on The OpenAPI document is at: `https://gitea.your.host/swagger.v1.json` -## Listing your issued tokens via the API - -As mentioned in -[#3842](https://github.com/go-gitea/gitea/issues/3842#issuecomment-397743346), -`/users/:name/tokens` is special and requires you to authenticate -using BasicAuth, as follows: - -### Using basic authentication: - -```sh -$ curl --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens -[{"name":"test","sha1":"..."},{"name":"dev","sha1":"..."}] -``` - -As of v1.8.0 of Gitea, if using basic authentication with the API and your user has two factor authentication enabled, you'll need to send an additional header that contains the one time password (6 digit rotating token). An example of the header is `X-Gitea-OTP: 123456` where `123456` is where you'd place the code from your authenticator. Here is how the request would look like in curl: - -```sh -$ curl -H "X-Gitea-OTP: 123456" --request GET --url https://yourusername:yourpassword@gitea.your.host/api/v1/users/yourusername/tokens -``` - ## Sudo The API allows admin users to sudo API requests as another user. Simply add either a `sudo=` parameter or `Sudo:` request header with the username of the user to sudo. diff --git a/docs/content/doc/developers/hacking-on-gitea.en-us.md b/docs/content/doc/developers/hacking-on-gitea.en-us.md index ede693ce179e4..360a46d20fbf1 100644 --- a/docs/content/doc/developers/hacking-on-gitea.en-us.md +++ b/docs/content/doc/developers/hacking-on-gitea.en-us.md @@ -127,7 +127,7 @@ See `make help` for all available `make` targets. Also see [`.drone.yml`](https: ## Building continuously -To run and continously rebuild when source files change: +To run and continuously rebuild when source files change: ```bash make watch @@ -216,7 +216,7 @@ You should validate your generated Swagger file and spell-check it with: make swagger-validate misspell-check ``` -You should commit the changed swagger JSON file. The continous integration +You should commit the changed swagger JSON file. The continuous integration server will check that this has been done using: ```bash @@ -315,7 +315,7 @@ branches as we will need to update it to main before merging and/or may be able to help fix issues directly. Any PR requires two approvals from the Gitea maintainers and needs to pass the -continous integration. Take a look at our +continuous integration. Take a look at our [`CONTRIBUTING.md`](https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md) document. diff --git a/docs/content/doc/features/authentication.en-us.md b/docs/content/doc/features/authentication.en-us.md index 0c83fa4d2f8d6..223d7aa4fb0cc 100644 --- a/docs/content/doc/features/authentication.en-us.md +++ b/docs/content/doc/features/authentication.en-us.md @@ -88,8 +88,8 @@ Adds the following fields: - Bind Password (optional) - The password for the Bind DN specified above, if any. _Note: The password - is stored in plaintext at the server. As such, ensure that the Bind DN - has as few privileges as possible._ + is stored encrypted with the SECRET_KEY on the server. It is still recommended + to ensure that the Bind DN has as few privileges as possible._ - User Search Base **(required)** 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 3449c191d68d7..53eaed3bb116b 100644 --- a/docs/content/doc/installation/with-docker-rootless.en-us.md +++ b/docs/content/doc/installation/with-docker-rootless.en-us.md @@ -107,7 +107,7 @@ services: + - db + + db: -+ image: mysql:5.7 ++ image: mysql:8 + restart: always + environment: + - MYSQL_ROOT_PASSWORD=gitea @@ -148,7 +148,7 @@ services: + - db + + db: -+ image: postgres:9.6 ++ image: postgres:13 + restart: always + environment: + - POSTGRES_USER=gitea diff --git a/docs/content/doc/installation/with-docker.en-us.md b/docs/content/doc/installation/with-docker.en-us.md index 83f82d85d6350..06917b5d8a411 100644 --- a/docs/content/doc/installation/with-docker.en-us.md +++ b/docs/content/doc/installation/with-docker.en-us.md @@ -137,7 +137,7 @@ services: + - db + + db: -+ image: mysql:5.7 ++ image: mysql:8 + restart: always + environment: + - MYSQL_ROOT_PASSWORD=gitea @@ -188,7 +188,7 @@ services: + - db + + db: -+ image: postgres:9.6 ++ image: postgres:13 + restart: always + environment: + - POSTGRES_USER=gitea diff --git a/docs/content/doc/installation/with-docker.zh-cn.md b/docs/content/doc/installation/with-docker.zh-cn.md index d32b774c201a0..f823e0d749596 100644 --- a/docs/content/doc/installation/with-docker.zh-cn.md +++ b/docs/content/doc/installation/with-docker.zh-cn.md @@ -122,7 +122,7 @@ services: + - db + + db: -+ image: mysql:5.7 ++ image: mysql:8 + restart: always + environment: + - MYSQL_ROOT_PASSWORD=gitea @@ -172,7 +172,7 @@ services: + - db + + db: -+ image: postgres:9.6 ++ image: postgres:13 + restart: always + environment: + - POSTGRES_USER=gitea diff --git a/integrations/README_ZH.md b/integrations/README_ZH.md index fd317645603a7..39639f9b89adf 100644 --- a/integrations/README_ZH.md +++ b/integrations/README_ZH.md @@ -26,7 +26,7 @@ make test-sqlite ## 如何使用 mysql 数据库进行集成测试 首先在docker容器里部署一个 mysql 数据库 ``` -docker run -e "MYSQL_DATABASE=test" -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" -p 3306:3306 --rm --name mysql mysql:5.7 #(just ctrl-c to stop db and clean the container) +docker run -e "MYSQL_DATABASE=test" -e "MYSQL_ALLOW_EMPTY_PASSWORD=yes" -p 3306:3306 --rm --name mysql mysql:8 #(just ctrl-c to stop db and clean the container) ``` 之后便可以基于这个数据库进行集成测试 ``` @@ -36,7 +36,7 @@ TEST_MYSQL_HOST=localhost:3306 TEST_MYSQL_DBNAME=test TEST_MYSQL_USERNAME=root T ## 如何使用 pgsql 数据库进行集成测试 同上,首先在 docker 容器里部署一个 pgsql 数据库 ``` -docker run -e "POSTGRES_DB=test" -p 5432:5432 --rm --name pgsql postgres:9.5 #(just ctrl-c to stop db and clean the container) +docker run -e "POSTGRES_DB=test" -p 5432:5432 --rm --name pgsql postgres:13 #(just ctrl-c to stop db and clean the container) ``` 之后便可以基于这个数据库进行集成测试 ``` diff --git a/models/admin.go b/models/admin.go index 7911ce75112cd..3a784d66964ab 100644 --- a/models/admin.go +++ b/models/admin.go @@ -114,6 +114,11 @@ func DeleteNotice(id int64) error { // DeleteNotices deletes all notices with ID from start to end (inclusive). func DeleteNotices(start, end int64) error { + if start == 0 && end == 0 { + _, err := x.Exec("DELETE FROM notice") + return err + } + sess := x.Where("id >= ?", start) if end > 0 { sess.And("id <= ?", end) diff --git a/models/avatar.go b/models/avatar.go index 4f02fe508981d..b4c078f8cf9ff 100644 --- a/models/avatar.go +++ b/models/avatar.go @@ -44,7 +44,7 @@ const DefaultAvatarSize = -1 const DefaultAvatarPixelSize = 28 // AvatarRenderedSizeFactor is the factor by which the default size is increased for finer rendering -const AvatarRenderedSizeFactor = 2 +const AvatarRenderedSizeFactor = 4 // HashEmail hashes email address to MD5 string. // https://en.gravatar.com/site/implement/hash/ diff --git a/models/login_source.go b/models/login_source.go index 57b1d56bb2bcd..098b48a8cd5f4 100644 --- a/models/login_source.go +++ b/models/login_source.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/auth/oauth2" "code.gitea.io/gitea/modules/auth/pam" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/secret" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -77,11 +78,25 @@ type LDAPConfig struct { // FromDB fills up a LDAPConfig from serialized format. func (cfg *LDAPConfig) FromDB(bs []byte) error { json := jsoniter.ConfigCompatibleWithStandardLibrary - return json.Unmarshal(bs, &cfg) + err := json.Unmarshal(bs, &cfg) + if err != nil { + return err + } + if cfg.BindPasswordEncrypt != "" { + cfg.BindPassword, err = secret.DecryptSecret(setting.SecretKey, cfg.BindPasswordEncrypt) + cfg.BindPasswordEncrypt = "" + } + return err } // ToDB exports a LDAPConfig to a serialized format. func (cfg *LDAPConfig) ToDB() ([]byte, error) { + var err error + cfg.BindPasswordEncrypt, err = secret.EncryptSecret(setting.SecretKey, cfg.BindPassword) + if err != nil { + return nil, err + } + cfg.BindPassword = "" json := jsoniter.ConfigCompatibleWithStandardLibrary return json.Marshal(cfg) } diff --git a/modules/auth/ldap/ldap.go b/modules/auth/ldap/ldap.go index 6c557de018c4b..91ad33a60f3a4 100644 --- a/modules/auth/ldap/ldap.go +++ b/modules/auth/ldap/ldap.go @@ -35,6 +35,7 @@ type Source struct { SecurityProtocol SecurityProtocol SkipVerify bool BindDN string // DN to bind with + BindPasswordEncrypt string // Encrypted Bind BN password BindPassword string // Bind DN password UserBase string // Base search path for users UserDN string // Template for the DN of the user for simple auth diff --git a/modules/git/command.go b/modules/git/command.go index fe258954628e0..ef78464d5f1c0 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -124,12 +124,18 @@ func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time. cmd := exec.CommandContext(ctx, c.name, c.args...) if env == nil { - cmd.Env = append(os.Environ(), fmt.Sprintf("LC_ALL=%s", DefaultLocale)) + cmd.Env = os.Environ() } else { cmd.Env = env - cmd.Env = append(cmd.Env, fmt.Sprintf("LC_ALL=%s", DefaultLocale)) } + cmd.Env = append( + cmd.Env, + fmt.Sprintf("LC_ALL=%s", DefaultLocale), + // avoid prompting for credentials interactively, supported since git v2.3 + "GIT_TERMINAL_PROMPT=0", + ) + // TODO: verify if this is still needed in golang 1.15 if goVersionLessThan115 { cmd.Env = append(cmd.Env, "GODEBUG=asyncpreemptoff=1") diff --git a/modules/private/hook.go b/modules/private/hook.go index 178500f7362dd..cb8fe25708a78 100644 --- a/modules/private/hook.go +++ b/modules/private/hook.go @@ -5,6 +5,7 @@ package private import ( + "encoding/json" "fmt" "net/http" "net/url" @@ -57,6 +58,12 @@ type HookOptions struct { IsDeployKey bool } +// SSHLogOption ssh log options +type SSHLogOption struct { + IsError bool + Message string +} + // HookPostReceiveResult represents an individual result from PostReceive type HookPostReceiveResult struct { Results []HookPostReceiveBranchResult @@ -146,3 +153,27 @@ func SetDefaultBranch(ownerName, repoName, branch string) error { } return nil } + +// SSHLog sends ssh error log response +func SSHLog(isErr bool, msg string) error { + reqURL := setting.LocalURL + "api/internal/ssh/log" + req := newInternalRequest(reqURL, "POST") + req = req.Header("Content-Type", "application/json") + + jsonBytes, _ := json.Marshal(&SSHLogOption{ + IsError: isErr, + Message: msg, + }) + req.Body(jsonBytes) + + req.SetTimeout(60*time.Second, 60*time.Second) + resp, err := req.Response() + if err != nil { + return fmt.Errorf("unable to contact gitea: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("Error returned from gitea: %v", decodeJSONError(resp).Err) + } + return nil +} diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 16677fe8a6844..ba69a7f97ca7e 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -112,13 +112,13 @@ func TestPushCommits_AvatarLink(t *testing.T) { pushCommits.Len = len(pushCommits.Commits) assert.Equal(t, - "https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=56", + "https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=112", pushCommits.AvatarLink("user2@example.com")) assert.Equal(t, "https://secure.gravatar.com/avatar/"+ fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com")))+ - "?d=identicon&s=56", + "?d=identicon&s=112", pushCommits.AvatarLink("nonexistent@example.com")) } diff --git a/modules/setting/log.go b/modules/setting/log.go index 44017b11383d4..0fb108c93dcf3 100644 --- a/modules/setting/log.go +++ b/modules/setting/log.go @@ -287,6 +287,7 @@ func newLogService() { options := newDefaultLogOptions() options.bufferLength = Cfg.Section("log").Key("BUFFER_LEN").MustInt64(10000) + EnableSSHLog = Cfg.Section("log").Key("ENABLE_SSH_LOG").MustBool(false) description := LogDescription{ Name: log.DEFAULT, diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 4244b55939b20..ec8e64578bf91 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -319,6 +319,7 @@ var ( DisableRouterLog bool RouterLogLevel log.Level EnableAccessLog bool + EnableSSHLog bool AccessLogTemplate string EnableXORMLog bool diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 3384d7f4844d4..8311cf6d895f8 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -2225,7 +2225,6 @@ auths.host=Server auths.port=Port auths.bind_dn=Připojení DN auths.bind_password=Heslo připojení -auths.bind_password_helper=Upozornění: Toto heslo je ukládáno v nešifrované podobě. Použijte účet pouze pro čtení, pokud je to možné. auths.user_base=Výchozí bod hledání uživatelů auths.user_dn=DN uživatele auths.attribute_username=Atribut uživatelského jména diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 85cab48289afa..0ca33c86f813c 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -2278,7 +2278,6 @@ auths.host=Host auths.port=Port auths.bind_dn=DN binden auths.bind_password=Passwort binden -auths.bind_password_helper=Achtung: Das Passwort wird im Klartext gespeichert. Benutze, wenn möglich, einen Account, der nur über Lesezugriff verfügt. auths.user_base=Basis für Benutzersuche auths.user_dn=Benutzer-DN auths.attribute_username=Benutzernamens-Attribut diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b41aa6a7913c6..a58b9d31e1851 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1553,6 +1553,7 @@ settings.email_notifications.disable = Disable Email Notifications settings.email_notifications.submit = Set Email Preference settings.site = Website settings.update_settings = Update Settings +settings.branches.update_default_branch = Update Default Branch settings.advanced_settings = Advanced Settings settings.wiki_desc = Enable Repository Wiki settings.use_internal_wiki = Use Built-In Wiki @@ -2285,7 +2286,6 @@ auths.host = Host auths.port = Port auths.bind_dn = Bind DN auths.bind_password = Bind Password -auths.bind_password_helper = Warning: This password is stored in plain text. Use a read-only account if possible. auths.user_base = User Search Base auths.user_dn = User DN auths.attribute_username = Username Attribute diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 88d5a09b887c2..92899a66508af 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -854,6 +854,7 @@ branch=Rama tree=Árbol clear_ref=`Borrar referencia actual` filter_branch_and_tag=Filtrar por rama o etiqueta +find_tag=Buscar etiqueta branches=Ramas tags=Etiquetas issues=Incidencias @@ -1158,7 +1159,7 @@ issues.label_color=Color etiqueta issues.label_count=%d etiquetas issues.label_open_issues=%d incidencias abiertas issues.label_edit=Editar -issues.label_delete=Borrar +issues.label_delete=Eliminar issues.label_modify=Editar etiqueta issues.label_deletion=Eliminar etiqueta issues.label_deletion_desc=Eliminar una etiqueta la elimina de todos las incidencias. ¿Continuar? @@ -1284,6 +1285,8 @@ issues.review.resolved_by=ha marcado esta conversación como resuelta issues.assignee.error=No todos los asignados fueron añadidos debido a un error inesperado. issues.reference_issue.body=Cuerpo +compare.compare_base=base +compare.compare_head=comparar pulls.desc=Activar Pull Requests y revisiones de código. pulls.new=Nuevo Pull Request @@ -1546,6 +1549,7 @@ settings.email_notifications.disable=Deshabilitar las notificaciones por correo settings.email_notifications.submit=Establecer Preferencia de correo electrónico settings.site=Sitio web settings.update_settings=Actualizar configuración +settings.branches.update_default_branch=Actualizar rama por defecto settings.advanced_settings=Ajustes avanzados settings.wiki_desc=Activar Wiki de repositorio settings.use_internal_wiki=Usar Wiki integrada @@ -1886,6 +1890,7 @@ diff.file_image_width=Anchura diff.file_image_height=Altura diff.file_byte_size=Tamaño diff.file_suppressed=La diferencia del archivo ha sido suprimido porque es demasiado grande +diff.file_suppressed_line_too_long=Las diferiencias del archivo han sido suprimidas porque una o mas lineas son muy largas diff.too_many_files=Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio diff.comment.placeholder=Deja un comentario diff.comment.markdown_info=Es posible estilizar con markdown. @@ -1913,6 +1918,7 @@ release.new_release=Nueva Release release.draft=Borrador release.prerelease=Pre-lanzamiento release.stable=Estable +release.compare=Comparar release.edit=editar release.ahead.commits=%d commits release.ahead.target=a %s desde esta versión @@ -2130,7 +2136,7 @@ dashboard.cron.error=Error en Cron: %s: %[3]s dashboard.cron.finished=Cron: %[1]s ha finalizado dashboard.delete_inactive_accounts=Eliminar todas las cuentas inactivas dashboard.delete_inactive_accounts.started=Se ha iniciado la tarea: "Eliminar todas las cuentas inactivas". -dashboard.delete_repo_archives=Borrar todos los archivos del repositorio (ZIP, TAR.GZ, etc.) +dashboard.delete_repo_archives=Eliminar todos los archivos del repositorio (ZIP, TAR.GZ, etc.) dashboard.delete_repo_archives.started=Se ha iniciado la tarea: "Eliminar todos los archivos del repositorios". dashboard.delete_missing_repos=Eliminar todos los repositorios que faltan sus archivos Git dashboard.delete_missing_repos.started=Se ha iniciado la tarea: "Eliminar todos los repositorios que faltan sus archivos Git". @@ -2179,6 +2185,8 @@ dashboard.total_gc_time=Pausa Total por GC dashboard.total_gc_pause=Pausa Total por GC dashboard.last_gc_pause=Última Pausa por GC dashboard.gc_times=Ejecuciones GC +dashboard.delete_old_actions=Eliminar todas las acciones antiguas de la base de datos +dashboard.delete_old_actions.started=Eliminar todas las acciones antiguas de la base de datos inicializada. users.user_manage_panel=Gestión de cuentas de usuario users.new_account=Crear Cuenta de Usuario @@ -2274,7 +2282,6 @@ auths.host=Servidor auths.port=Puerto auths.bind_dn=Bind DN auths.bind_password=Contraseña Bind -auths.bind_password_helper=Advertencia: Esta contraseña se almacena en texto plano. Utilice una cuenta de sólo lectura si es posible. auths.user_base=Base de búsqueda de usuarios auths.user_dn=DN de Usuario auths.attribute_username=Atributo nombre de usuario @@ -2305,6 +2312,7 @@ auths.allowed_domains_helper=Dejar vacío para permitir todos los dominios. Sepa auths.enable_tls=Habilitar cifrado TLS auths.skip_tls_verify=Omitir la verificación TLS auths.pam_service_name=Nombre del Servicio PAM +auths.pam_email_domain=Dominio de correo de PAM (opcional) auths.oauth2_provider=Proveedor OAuth2 auths.oauth2_icon_url=URL de icono auths.oauth2_clientID=ID de cliente (clave) @@ -2404,6 +2412,7 @@ config.db_path=Ruta config.service_config=Configuración del servicio config.register_email_confirm=Requerir confirmación de correo electrónico para registrarse config.disable_register=Deshabilitar auto-registro +config.allow_only_internal_registration=Permitir el registro solo desde Gitea config.allow_only_external_registration=Permitir el registro únicamente a través de servicios externos config.enable_openid_signup=Habilitar el auto-registro con OpenID config.enable_openid_signin=Habilitar el inicio de sesión con OpenID diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 1cd98fca0dc39..c36d683e1f965 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -1896,7 +1896,6 @@ auths.host=میزبان auths.port=درگاه (پورت) auths.bind_dn=DN متصل شده auths.bind_password=اتصال گذرواژه -auths.bind_password_helper=هشدار: این گذرواژه به صورت متن خام ذخیره می شود. استفاده حساب های کاربری فقط-خواندنی امکان پذیر هست. auths.user_base=پایگاه جستجوی کاربر auths.user_dn=کاربر DN auths.attribute_username=ویژگی نام کاربری diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 8e95f9e9d64ad..2f73f550e2eea 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -2222,7 +2222,6 @@ auths.host=Hôte auths.port=Port auths.bind_dn=Bind DN auths.bind_password=Bind mot de passe -auths.bind_password_helper=Attention: ce mot de passe est stocké en clair. Veuillez utiliser, si possible, un compte avec des droits limités en lecture seule. auths.user_base=Utilisateur Search Base auths.user_dn=Utilisateur DN auths.attribute_username=Attribut nom d'utilisateur diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index d08bd9f4c94ff..6e6a81e16a3e6 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -1495,7 +1495,6 @@ auths.host=Kiszolgáló auths.port=Port auths.bind_dn=Bind DN auths.bind_password=Bind Jelszó -auths.bind_password_helper=Figyelem: Ez a jelszó egyszerű szövegben van tárolva. Ha lehetséges használjon csak olvasható fiókot. auths.user_base=Felhasználókeresés alapja (BaseDN) auths.user_dn=Felhasználói DN auths.attribute_username=Felhasználónév attribútum diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index bebac4dc9f49f..657c8afecfa2e 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -2097,7 +2097,6 @@ auths.host=Host auths.port=Porta auths.bind_dn=Binda DN auths.bind_password=Binda Password -auths.bind_password_helper=Attenzione: La password è memorizzata in testo normale. Se possibile, utilizzare un account di sola lettura. auths.user_base=Base ricerca utente auths.user_dn=DN dell'utente auths.attribute_username=Attributo nome utente diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index c583ff7848ff6..727b68cb7e886 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -1285,6 +1285,8 @@ issues.review.resolved_by=がこの会話を解決済みにしました issues.assignee.error=予期しないエラーにより、一部の担当者を追加できませんでした。 issues.reference_issue.body=内容 +compare.compare_base=基準 +compare.compare_head=比較 pulls.desc=プルリクエストとコードレビューの有効化。 pulls.new=新しいプルリクエスト @@ -1547,6 +1549,7 @@ settings.email_notifications.disable=メール通知無効 settings.email_notifications.submit=メール設定を保存 settings.site=Webサイト settings.update_settings=設定を更新 +settings.branches.update_default_branch=デフォルトブランチを更新 settings.advanced_settings=拡張設定 settings.wiki_desc=Wikiを有効にする settings.use_internal_wiki=ビルトインのWikiを使用する @@ -1887,6 +1890,7 @@ diff.file_image_width=幅 diff.file_image_height=高さ diff.file_byte_size=サイズ diff.file_suppressed=ファイル差分が大きすぎるため省略します +diff.file_suppressed_line_too_long=長すぎる行があるためファイル差分は表示されません diff.too_many_files=変更されたファイルが多すぎるため、一部のファイルは表示されません diff.comment.placeholder=コメントを残す diff.comment.markdown_info=Markdownによる書式設定をサポートしています。 @@ -2278,7 +2282,6 @@ auths.host=ホスト auths.port=ポート auths.bind_dn=バインドDN auths.bind_password=バインドパスワード -auths.bind_password_helper=警告: このパスワードはプレーンテキストで保存されます。 可能であれば読み取り専用アカウントを使用してください。 auths.user_base=ユーザー検索ベース auths.user_dn=ユーザーDN auths.attribute_username=ユーザー名 @@ -2309,6 +2312,7 @@ auths.allowed_domains_helper=すべてのドメインを許可する場合は空 auths.enable_tls=TLS暗号化を有効にする auths.skip_tls_verify=TLS検証を省略 auths.pam_service_name=PAMサービス名 +auths.pam_email_domain=PAM メールドメイン名 (オプション) auths.oauth2_provider=OAuth2プロバイダー auths.oauth2_icon_url=アイコンのURL auths.oauth2_clientID=クライアントID (キー) @@ -2408,6 +2412,7 @@ config.db_path=パス config.service_config=サービス設定 config.register_email_confirm=登録にはメールによる確認が必要 config.disable_register=セルフ登録無効 +config.allow_only_internal_registration=Gitea上での登録のみを許可 config.allow_only_external_registration=外部サービスを使用した登録のみを許可 config.enable_openid_signup=OpenIDを使ったセルフ登録有効 config.enable_openid_signin=OpenIDを使ったサインイン有効 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 59e8cffe36ebf..ca28c1a186246 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -2248,7 +2248,6 @@ auths.host=Resursdators auths.port=Ports auths.bind_dn=Saistīšanas DN auths.bind_password=Saistīšanas parole -auths.bind_password_helper=Brīdinājums: Šī parole tiks glabāta nešifrētā veidā. Ieteicams izmantot kontu ar tikai lasīšanas tiesībām. auths.user_base=Lietotāja pamatnosacījumi auths.user_dn=Lietotāja DN auths.attribute_username=Lietotājvārda atribūts diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index dbaec92406914..287835aa325f8 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -2118,7 +2118,6 @@ auths.host=Host auths.port=Poort auths.bind_dn=Binden DN auths.bind_password=Bind wachtwoord -auths.bind_password_helper=Waarschuwing: Dit wachtwoord wordt opgeslagen in platte tekst. Indien mogelijk gebruik dan een alleen-lezen account. auths.user_base=User Search Base auths.user_dn=User DN auths.attribute_username=Gebruikersnaam attribuut diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 2155d60944f1c..8d37146e05151 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -2027,7 +2027,6 @@ auths.host=Serwer auths.port=Port auths.bind_dn=DN powiązania auths.bind_password=Hasło Bind -auths.bind_password_helper=Uwaga: To hasło będzie przechowywane w czystym tekście. Użyj konta "tylko do odczytu", jeśli to możliwe. auths.user_base=Baza wyszukiwania auths.user_dn=DN użytkownika auths.attribute_username=Atrybut nazwy użytkownika diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index dbcf1ca5a9d42..473da2d2705d6 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -2016,7 +2016,6 @@ auths.host=Servidor auths.port=Porta auths.bind_dn=Vincular DN auths.bind_password=Vincular senha -auths.bind_password_helper=Atenção: Esta senha é armazenada em texto sem formatação. Se possível, use uma conta de somente leitura. auths.user_base=Base de pesquisa do usuário auths.user_dn=Usuário do DN auths.attribute_username=Atributo nome de usuário diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index fee0d83204374..be2d98a97cf11 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -411,7 +411,7 @@ org_still_own_repo=Esta organização ainda possui repositórios; deve excluí-l target_branch_not_exist=O ramo de destino não existe. [user] -change_avatar=Alterar seu avatar… +change_avatar=Mude o seu avatar… join_on=Inscreveu-se em repositories=Repositórios activity=Trabalho público @@ -459,7 +459,7 @@ update_theme=Substituir tema update_profile=Modificar perfil update_language_not_found=O idioma '%s' não está disponível. update_profile_success=O seu perfil foi modificado. -change_username=Seu nome de utilizador foi alterado. +change_username=O seu nome de utilizador foi modificado. change_username_prompt=Nota: alterações do nome de utilizador também alteram o URL de sua conta. change_username_redirect_prompt=O antigo nome de utilizador, enquanto não for reivindicado, irá reencaminhar para o novo. continue=Continuar @@ -770,7 +770,7 @@ template.issue_labels=Rótulos das questões template.one_item=Tem que escolher pelo menos um item do modelo template.invalid=Tem que escolher um repositório modelo -archive.title=Este repositório está arquivado. Pode ver ficheiros e cloná-lo, mas não pode empurrar ou lançar questões ou pedidos de integração. +archive.title=Este repositório está arquivado. Pode ver os seus ficheiros e cloná-lo, mas não pode fazer envios para o repositório nem lançar questões ou fazer pedidos de integração. archive.issue.nocomment=Este repositório está arquivado. Não pode comentar nas questões. archive.pull.nocomment=Este repositório está arquivado. Não pode comentar nos pedidos de integração. @@ -839,7 +839,7 @@ no_desc=Sem descrição quick_guide=Guia rápido clone_this_repo=Clonar este repositório create_new_repo_command=Criando um novo repositório na linha de comandos -push_exist_repo=Empurrando um repositório existente pela linha de comandos +push_exist_repo=Enviando um repositório existente pela linha de comandos empty_message=Este repositório não contém qualquer conteúdo. code=Código @@ -889,22 +889,22 @@ lines=linhas editor.new_file=Novo ficheiro editor.upload_file=Carregar ficheiro editor.edit_file=Editar ficheiro -editor.preview_changes=Pré-visualizar alterações +editor.preview_changes=Pré-visualizar modificações editor.cannot_edit_lfs_files=Ficheiros LFS não podem ser editados na interface web. editor.cannot_edit_non_text_files=Ficheiros binários não podem ser editados na interface da web. editor.edit_this_file=Editar ficheiro editor.this_file_locked=Ficheiro bloqueado -editor.must_be_on_a_branch=Tem que estar num ramo para fazer ou propor alterações neste ficheiro. -editor.fork_before_edit=Tem que fazer uma derivação deste repositório para fazer ou propor alterações neste ficheiro. +editor.must_be_on_a_branch=Tem que estar num ramo para fazer ou propor modificações neste ficheiro. +editor.fork_before_edit=Tem que fazer uma derivação deste repositório para fazer ou propor modificações neste ficheiro. editor.delete_this_file=Eliminar ficheiro -editor.must_have_write_access=Tem que ter permissões de escrita para fazer ou propor alterações neste ficheiro. +editor.must_have_write_access=Tem que ter permissões de escrita para fazer ou propor modificações neste ficheiro. editor.file_delete_success=O ficheiro '%s' foi eliminado. editor.name_your_file=Nomeie o seu ficheiro… editor.filename_help=Adicione uma pasta escrevendo o nome dessa pasta seguido de uma barra('/'). Remova uma pasta carregando na tecla de apagar ('←') no início do campo. editor.or=ou editor.cancel_lower=Cancelar -editor.commit_signed_changes=Cometer alterações assinadas -editor.commit_changes=Cometer alterações +editor.commit_signed_changes=Cometer modificações assinadas +editor.commit_changes=Cometer modificações editor.add_tmpl=Adicionar '' editor.add=Adicionar '%s' editor.update=Modificar '%s' @@ -914,7 +914,7 @@ editor.signoff_desc=Adicionar "Assinado-por" seguido do autor do cometimento no editor.commit_directly_to_this_branch=Cometer imediatamente no ramo %s. editor.create_new_branch=Crie um novo ramo para este cometimento e inicie um pedido de integração. editor.create_new_branch_np=Criar um novo ramo para este cometimento. -editor.propose_file_change=Propor alteração de ficheiro +editor.propose_file_change=Propor modificação do ficheiro editor.new_branch_name_desc=Nome do novo ramo… editor.cancel=Cancelar editor.filename_cannot_be_empty=O nome do ficheiro não pode estar em branco. @@ -930,11 +930,11 @@ editor.file_changed_while_editing=O conteúdo do ficheiro mudou desde que começ editor.file_already_exists=Já existe um ficheiro com o nome '%s' neste repositório. editor.commit_empty_file_header=Cometer um ficheiro vazio editor.commit_empty_file_text=O ficheiro que está prestes a cometer está vazio. Quer continuar? -editor.no_changes_to_show=Não existem alterações a mostrar. +editor.no_changes_to_show=Não existem modificações para mostrar. editor.fail_to_update_file=Falhou ao modificar/criar o ficheiro '%s'. editor.fail_to_update_file_summary=Mensagem de erro: -editor.push_rejected_no_message=A alteração foi rejeitada pelo servidor sem qualquer mensagem. Verifique os automatismos do Git. -editor.push_rejected=A alteração foi rejeitada pelo servidor. Verifique os automatismos do Git. +editor.push_rejected_no_message=A modificação foi rejeitada pelo servidor sem qualquer mensagem. Verifique os automatismos do Git. +editor.push_rejected=A modificação foi rejeitada pelo servidor. Verifique os automatismos do Git. editor.push_rejected_summary=Mensagem completa de rejeição: editor.add_subdir=Adicionar uma pasta… editor.unable_to_upload_files=Falhou o carregamento de ficheiros para '%s' com o erro: %v @@ -942,10 +942,10 @@ editor.upload_file_is_locked=O ficheiro '%s' está bloqueado por %s. editor.upload_files_to_dir=Carregar ficheiros para '%s' editor.cannot_commit_to_protected_branch=Não é possível cometer para o ramo protegido '%s'. editor.no_commit_to_branch=Não é possível cometer imediatamente para o ramo porque: -editor.user_no_push_to_branch=O utilizador não pode empurrar para o ramo +editor.user_no_push_to_branch=O utilizador não pode enviar para o ramo editor.require_signed_commit=O ramo requer um cometimento assinado -commits.desc=Navegar pelo histórico de alterações no código fonte. +commits.desc=Navegar pelo histórico de modificações no código fonte. commits.commits=Cometimentos commits.no_commits=Não há cometimentos em comum. '%s' e '%s' têm históricos completamente diferentes. commits.search=Procurar cometimentos… @@ -1136,7 +1136,7 @@ issues.poster=Autor issues.collaborator=Colaborador(a) issues.owner=Proprietário(a) issues.re_request_review=Voltar a solicitar revisão -issues.is_stale=Houve alterações neste pedido de integração posteriormente a esta revisão +issues.is_stale=Houve modificações neste pedido de integração posteriormente a esta revisão issues.remove_request_review=Remover solicitação de revisão issues.remove_request_review_block=Não é possível remover a solicitação de revisão issues.dismiss_review=Descartar revisão @@ -1211,6 +1211,7 @@ issues.error_modifying_due_date=Falhou a modificação da data de vencimento. issues.error_removing_due_date=Falhou a remoção da data de vencimento. issues.push_commit_1=adicionou %d cometimento %s issues.push_commits_n=adicionou %d cometimentos %s +issues.force_push_codes=`forçou o envio %[1]s de %[2]s para %[4]s %[6]s` issues.due_date_form=yyyy-mm-dd issues.due_date_form_add=Adicionar data de vencimento issues.due_date_form_edit=Editar @@ -1250,14 +1251,14 @@ issues.dependency.add_error_dep_exists=A dependência já existe. issues.dependency.add_error_cannot_create_circular=Não pode criar uma dependência onde duas questões se bloqueiam simultaneamente. issues.dependency.add_error_dep_not_same_repo=Ambas as questões têm que estar no mesmo repositório. issues.review.self.approval=Não pode aprovar o seu próprio pedido de integração. -issues.review.self.rejection=Não pode solicitar alterações sobre o seu próprio pedido de integração. -issues.review.approve=aprovou estas alterações %s +issues.review.self.rejection=Não pode solicitar modificações sobre o seu próprio pedido de integração. +issues.review.approve=aprovou estas modificações %s issues.review.comment=reviu %s issues.review.dismissed=descartou a revisão de %s %s issues.review.dismissed_label=Descartada issues.review.left_comment=deixou um comentário -issues.review.content.empty=Tem que deixar um comentário indicando a(s) alteração(ões) solicitada(s). -issues.review.reject=alterações solicitadas %s +issues.review.content.empty=Tem que deixar um comentário indicando a(s) modificação(ões) solicitada(s). +issues.review.reject=modificações solicitadas %s issues.review.wait=foi solicitada para revisão %s issues.review.add_review_request=solicitou revisão de %s %s issues.review.remove_review_request=removeu a solicitação de revisão para %s %s @@ -1306,18 +1307,18 @@ pulls.has_merged=A integração constante no pedido foi executada. pulls.title_wip_desc=`Inicie o título com %s para evitar que o pedido de integração seja executado acidentalmente.` pulls.cannot_merge_work_in_progress=Este pedido de integração está marcado como um trabalho em andamento. Remova o prefixo %s do título quando estiver pronto pulls.data_broken=Este pedido de integração está danificado devido à falta de informação da derivação. -pulls.files_conflicted=Este pedido de integração contém alterações que entram em conflito com o ramo de destino. +pulls.files_conflicted=Este pedido de integração contém modificações que entram em conflito com o ramo de destino. pulls.is_checking=Está em andamento uma verificação de conflitos na integração. Tente novamente daqui a alguns momentos. pulls.is_empty=Este ramo é igual ao ramo de destino. pulls.required_status_check_failed=Algumas das verificações obrigatórias não foram bem sucedidas. pulls.required_status_check_missing=Estão faltando algumas verificações necessárias. pulls.required_status_check_administrator=Uma vez que é administrador, ainda pode realizar a integração deste pedido. pulls.blocked_by_approvals=Este pedido de integração ainda não tem aprovações suficientes. Já foram concedidas %d de um total de%d aprovações. -pulls.blocked_by_rejection=Este pedido de integração tem alterações solicitadas por um revisor oficial. +pulls.blocked_by_rejection=Este pedido de integração tem modificações solicitadas por um revisor oficial. pulls.blocked_by_official_review_requests=Este pedido de integração tem pedidos de revisão oficiais. pulls.blocked_by_outdated_branch=Este pedido de integração foi bloqueado por ser obsoleto. -pulls.blocked_by_changed_protected_files_1=Este pedido de integração está bloqueado porque altera um ficheiro protegido: -pulls.blocked_by_changed_protected_files_n=Este pedido de integração está bloqueado porque altera ficheiros protegidos: +pulls.blocked_by_changed_protected_files_1=Este pedido de integração está bloqueado porque modifica um ficheiro protegido: +pulls.blocked_by_changed_protected_files_n=Este pedido de integração está bloqueado porque modifica ficheiros protegidos: pulls.can_auto_merge_desc=A integração constante neste pedido pode ser executada automaticamente. pulls.cannot_auto_merge_desc=A integração constante neste pedido não pode ser executada automaticamente porque existem conflitos. pulls.cannot_auto_merge_helper=Faça a integração manualmente para resolver os conflitos. @@ -1325,8 +1326,8 @@ pulls.num_conflicting_files_1=%d ficheiro em conflito pulls.num_conflicting_files_n=%d ficheiros em conflito pulls.approve_count_1=%d aprovação pulls.approve_count_n=%d aprovações -pulls.reject_count_1=%d pedido de alteração -pulls.reject_count_n=%d pedidos de alteração +pulls.reject_count_1=%d pedido de modificação +pulls.reject_count_n=%d pedidos de modificação pulls.waiting_count_1=%d revisão pendente pulls.waiting_count_n=%d revisões pendentes pulls.wrong_commit_id=ID do cometimento tem que ser um ID de cometimento no ramo de destino @@ -1351,9 +1352,9 @@ pulls.rebase_conflict_summary=Mensagem de erro ; %[2]s
%[3]s
pulls.unrelated_histories=A integração falhou: A cabeça da integração e a base não partilham um histórico comum. Dica: Tente uma estratégia diferente pulls.merge_out_of_date=Falhou a integração: Enquanto estava a gerar a integração, a base foi modificada. Dica: Tente de novo. -pulls.push_rejected=A integração falhou: O empurrão foi rejeitado. Reveja os automatismos do Git neste repositório. +pulls.push_rejected=A integração falhou: O envio foi rejeitado. Reveja os automatismos do Git neste repositório. pulls.push_rejected_summary=Mensagem completa de rejeição -pulls.push_rejected_no_message=A integração falhou: O empurrão foi rejeitado mas não houve qualquer mensagem remota.
Reveja os automatismos do git para este repositório +pulls.push_rejected_no_message=A integração falhou: O envio foi rejeitado mas não houve qualquer mensagem remota.
Reveja os automatismos do git para este repositório pulls.open_unmerged_pull_exists=`Não pode executar uma operação de reabertura porque há um pedido de integração pendente (#%d) com propriedades idênticas.` pulls.status_checking=Algumas verificações estão pendentes pulls.status_checks_success=Todas as verificações foram bem sucedidas @@ -1370,8 +1371,8 @@ pulls.closed_at=`fechou este pedido de integração pulls.reopened_at=`reabriu este pedido de integração %[2]s` pulls.merge_instruction_hint=`Também pode ver as instruções para a linha de comandos.` -pulls.merge_instruction_step1_desc=No repositório do seu projecto, crie um novo ramo e teste as alterações. -pulls.merge_instruction_step2_desc=Integre as alterações e sincronize no Gitea. +pulls.merge_instruction_step1_desc=No repositório do seu projecto, crie um novo ramo e teste as modificações. +pulls.merge_instruction_step2_desc=Integre as modificações e sincronize no Gitea. milestones.new=Nova etapa milestones.open_tab=%d abertas @@ -1483,7 +1484,7 @@ activity.new_issues_count_n=Novas questões activity.new_issue_label=Em aberto activity.title.unresolved_conv_1=%d diálogo não resolvido activity.title.unresolved_conv_n=%d diálogos não resolvidos -activity.unresolved_conv_desc=Estas questões e estes pedidos de integração que foram alterados recentemente ainda não foram resolvidos. +activity.unresolved_conv_desc=Estas questões e estes pedidos de integração que foram modificados recentemente ainda não foram resolvidos. activity.unresolved_conv_label=Em aberto activity.title.releases_1=%d lançamento activity.title.releases_n=%d Lançamentos @@ -1493,8 +1494,8 @@ activity.no_git_activity=Não houve quaisquer cometimentos feitos durante este p activity.git_stats_exclude_merges=Excluindo integrações, activity.git_stats_author_1=%d autor activity.git_stats_author_n=%d autores -activity.git_stats_pushed_1=empurrou -activity.git_stats_pushed_n=empurraram +activity.git_stats_pushed_1=enviou +activity.git_stats_pushed_n=enviaram activity.git_stats_commit_1=%d cometimento activity.git_stats_commit_n=%d cometimentos activity.git_stats_push_to_branch=para o ramo %s e @@ -1502,8 +1503,8 @@ activity.git_stats_push_to_all_branches=para todos os ramos. activity.git_stats_on_default_branch=No ramo %s, activity.git_stats_file_1=%d ficheiro activity.git_stats_file_n=%d ficheiros -activity.git_stats_files_changed_1=foi alterado -activity.git_stats_files_changed_n=foram alterados +activity.git_stats_files_changed_1=foi modificado +activity.git_stats_files_changed_n=foram modificados activity.git_stats_additions=e houve activity.git_stats_addition_1=%d adição activity.git_stats_addition_n=%d adições @@ -1641,7 +1642,7 @@ settings.add_team=Adicionar equipa settings.add_team_duplicate=A equipa já tem o repositório settings.add_team_success=A equipa agora tem acesso ao repositório. settings.search_team=Procurar equipa… -settings.change_team_permission_tip=A permissão da equipa é definida na página de configurações da equipa e não pode ter alterações específicas de cada repositório +settings.change_team_permission_tip=A permissão da equipa é definida na página de configurações da equipa e não pode ter modificações específicas de cada repositório settings.delete_team_tip=Esta equipa tem acesso a todos os repositórios e não pode ser removida settings.remove_team_success=O acesso da equipa ao repositório foi removido. settings.add_webhook=Adicionar automatismo web @@ -1674,7 +1675,7 @@ settings.discord_username=Nome de utilizador settings.discord_icon_url=URL do ícone settings.slack_color=Cor settings.event_desc=Despoletado por: -settings.event_push_only=Eventos de empurrar +settings.event_push_only=Eventos de envio settings.event_send_everything=Todos os eventos settings.event_choose=Eventos personalizados… settings.event_header_repository=Eventos do repositório @@ -1686,8 +1687,8 @@ settings.event_fork=Derivar settings.event_fork_desc=Feita a derivação do repositório. settings.event_release=Lançamento settings.event_release_desc=Lançamento publicado, modificado ou eliminado num repositório. -settings.event_push=Empurrar -settings.event_push_desc=Empurrão de Git para um repositório. +settings.event_push=Enviar +settings.event_push_desc=Envio do Git para um repositório. settings.event_repository=Repositório settings.event_repository_desc=Repositório criado ou eliminado. settings.event_header_issue=Eventos da questão @@ -1717,7 +1718,7 @@ settings.event_pull_request_review_desc=Pedido de integração aprovado, rejeita settings.event_pull_request_sync=Pedido de integração sincronizado settings.event_pull_request_sync_desc=Pedido de integração sincronizado. settings.branch_filter=Filtro por ramo -settings.branch_filter_desc=Lista branca para eventos de empurrar e de criar e eliminar ramos, especificada como um padrão glob. Se estiver em branco ou for *, serão reportados eventos para todos os ramos. Veja a documentação github.com/gobwas/glob para detalhes da sintaxe. Exemplos: master, {master,release*}. +settings.branch_filter_desc=Lista de permissões do ramo para eventos de envio e de criação e eliminação de ramos, especificada como um padrão glob. Se estiver em branco ou for *, serão reportados eventos para todos os ramos. Veja a documentação github.com/gobwas/glob para detalhes da sintaxe. Exemplos: trunk, {trunk,release*}. settings.active=Em funcionamento settings.active_helper=Informação sobre eventos despoletados será enviada para o URL deste automatismo web. settings.add_hook_success=O automatismo web foi adicionado. @@ -1740,7 +1741,7 @@ settings.deploy_keys=Chaves de instalação settings.add_deploy_key=Adicionar chave de instalação settings.deploy_key_desc=Chaves de instalação têm acesso para puxar do repositório apenas em modo de leitura. settings.is_writable=Habilitar acesso de escrita -settings.is_writable_info=Permitir a esta chave de instalação empurrar para o repositório. +settings.is_writable_info=Permitir a esta chave de instalação enviar para o repositório. settings.no_deploy_keys=Ainda não existem quaisquer chaves de instalação. settings.title=Título settings.deploy_key_content=Conteúdo @@ -1752,29 +1753,29 @@ settings.deploy_key_deletion_desc=Remover uma chave de instalação irá revogar settings.deploy_key_deletion_success=A chave de instalação foi removida. settings.branches=Ramos settings.protected_branch=Salvaguarda do ramo -settings.protected_branch_can_push=Permitir empurrão? -settings.protected_branch_can_push_yes=Pode empurrar -settings.protected_branch_can_push_no=Não pode empurrar +settings.protected_branch_can_push=Permitir envios? +settings.protected_branch_can_push_yes=Pode enviar +settings.protected_branch_can_push_no=Não pode enviar settings.branch_protection=Salvaguarda do ramo '%s' settings.protect_this_branch=Habilitar salvaguarda do ramo -settings.protect_this_branch_desc=Impede a eliminação e restringe o empurrar e o integrar do Git no ramo. -settings.protect_disable_push=Desabilitar empurrão -settings.protect_disable_push_desc=Empurrar para este ramo não será permitido. -settings.protect_enable_push=Habilitar empurrão -settings.protect_enable_push_desc=Qualquer utilizador com acesso de escrita terá permissão para empurrar para este ramo (mas não poderá empurrar forçadamente). -settings.protect_whitelist_committers=Lista de permissão restrita para empurrar -settings.protect_whitelist_committers_desc=Apenas os utilizadores ou equipas da lista terão permissão para empurrar para este ramo (mas não poderão empurrar forçadamente). -settings.protect_whitelist_deploy_keys=Dar permissão às chaves de instalação para terem acesso de escrita para empurrar. -settings.protect_whitelist_users=Utilizadores com permissão para empurrar: +settings.protect_this_branch_desc=Impede a eliminação e restringe envios e integrações do Git no ramo. +settings.protect_disable_push=Desabilitar envios +settings.protect_disable_push_desc=O envio para este ramo não será permitido. +settings.protect_enable_push=Habilitar envios +settings.protect_enable_push_desc=Qualquer utilizador com acesso de escrita terá permissão para enviar para este ramo (mas não poderá fazer envios forçados). +settings.protect_whitelist_committers=Lista de permissões para restringir os envios +settings.protect_whitelist_committers_desc=Apenas os utilizadores ou equipas constantes na lista terão permissão para enviar para este ramo (mas não poderão fazer envios forçados). +settings.protect_whitelist_deploy_keys=Dar permissão às chaves de instalação para terem acesso de escrita para enviar. +settings.protect_whitelist_users=Utilizadores com permissão para enviar: settings.protect_whitelist_search_users=Procurar utilizadores… -settings.protect_whitelist_teams=Equipas com permissão para empurrar: +settings.protect_whitelist_teams=Equipas com permissão para enviar: settings.protect_whitelist_search_teams=Procurar equipas… settings.protect_merge_whitelist_committers=Habilitar lista de permissão para integrar settings.protect_merge_whitelist_committers_desc=Permitir que somente utilizadores ou equipas constantes na lista de permissão possam executar, neste ramo, integrações constantes em pedidos de integração. settings.protect_merge_whitelist_users=Utilizadores com permissão para executar integrações: settings.protect_merge_whitelist_teams=Equipas com permissão para executar integrações: settings.protect_check_status_contexts=Habilitar verificação de estado -settings.protect_check_status_contexts_desc=Exigir que as verificações de estado passem antes de ser aplicada a integração. Escolha quais as verificações de estado que têm de passar para que os ramos possam ser integrados num ramo que corresponda a esta regra. Quando habilitado, os cometimentos primeiro têm de ser empurrados para outro ramo e depois integrados, ou então empurrados imediatamente para um ramo que corresponda a esta regra, após terem passado as verificações de estado. Se não forem escolhidos quaisquer contextos, o último cometimento tem que ser bem sucedido, independentemente do contexto. +settings.protect_check_status_contexts_desc=Exigir que as verificações de estado passem antes de ser aplicada a integração. Escolha quais as verificações de estado que têm de passar para que os ramos possam ser integrados num ramo que corresponda a esta regra. Quando habilitado, os cometimentos primeiro têm de ser enviados para outro ramo e depois integrados, ou então enviados imediatamente para um ramo que corresponda a esta regra, após terem passado as verificações de estado. Se não forem escolhidos quaisquer contextos, o último cometimento tem que ser bem sucedido, independentemente do contexto. settings.protect_check_status_contexts_list=Verificações de estado encontradas na última semana para este repositório settings.protect_required_approvals=Aprovações necessárias: settings.protect_required_approvals_desc=Permitir somente a integração constante de pedidos que tenham revisões positivas suficientes. @@ -1783,19 +1784,19 @@ settings.protect_approvals_whitelist_enabled_desc=Somente as revisões dos utili settings.protect_approvals_whitelist_users=Revisores com permissão: settings.protect_approvals_whitelist_teams=Equipas com permissão para rever: settings.dismiss_stale_approvals=Descartar aprovações obsoletas -settings.dismiss_stale_approvals_desc=Quando novos cometimentos que mudam o conteúdo do pedido de integração forem empurrados para o ramo, as aprovações antigas serão descartadas. +settings.dismiss_stale_approvals_desc=Quando novos cometimentos que mudam o conteúdo do pedido de integração forem enviados para o ramo, as aprovações antigas serão descartadas. settings.require_signed_commits=Exigir cometimentos assinados -settings.require_signed_commits_desc=Rejeitar empurrões para este ramo se não estiverem assinados ou não forem verificáveis. +settings.require_signed_commits_desc=Rejeitar envios para este ramo que não estejam assinados ou que não sejam verificáveis. settings.protect_protected_file_patterns=Padrões de ficheiros protegidos (separados com ponto e vírgula '\;'): -settings.protect_protected_file_patterns_desc=Ficheiros protegidos que não podem ser alterados, mesmo que o utilizador tenha direitos para adicionar, editar ou eliminar ficheiros neste ramo. Múltiplos padrões podem ser separados com ponto e vírgula ('\;'). Veja a documentação em github.com/gobwas/glob para ver a sintaxe. Exemplos: .drone.yml, /docs/**/*.txt. +settings.protect_protected_file_patterns_desc=Ficheiros protegidos que não podem ser modificados, mesmo que o utilizador tenha direitos para adicionar, editar ou eliminar ficheiros neste ramo. Múltiplos padrões podem ser separados com ponto e vírgula ('\;'). Veja a documentação em github.com/gobwas/glob para ver a sintaxe. Exemplos: .drone.yml, /docs/**/*.txt. settings.add_protected_branch=Habilitar salvaguarda settings.delete_protected_branch=Desabilitar salvaguarda settings.update_protect_branch_success=A salvaguarda do ramo '%s' foi modificada. settings.remove_protected_branch_success=A salvaguarda do ramo '%s' foi desabilitada. settings.protected_branch_deletion=Desabilitar salvaguarda do ramo -settings.protected_branch_deletion_desc=Desabilitar a salvaguarda do ramo irá permitir que os utilizadores que tenham permissão de escrita empurrem para o ramo. Quer continuar? +settings.protected_branch_deletion_desc=Desabilitar a salvaguarda do ramo irá permitir que os utilizadores que tenham permissão de escrita enviem para o ramo. Quer continuar? settings.block_rejected_reviews=Bloquear a integração quando há revisões rejeitadas -settings.block_rejected_reviews_desc=A integração não será possível quando as alterações forem pedidas pelos revisores oficiais, mesmo que haja aprovações suficientes. +settings.block_rejected_reviews_desc=A integração não será possível quando as modificações forem pedidas pelos revisores oficiais, mesmo que haja aprovações suficientes. settings.block_on_official_review_requests=Bloquear integração nos pedidos de revisão oficiais settings.block_on_official_review_requests_desc=A integração não será possível quando tiver pedidos de revisão oficiais, mesmo que haja aprovações suficientes. settings.block_outdated_branch=Bloquear integração se o pedido de integração for obsoleto @@ -1821,7 +1822,7 @@ settings.archive.error_ismirror=Não pode arquivar um repositório que tenha sid settings.archive.branchsettings_unavailable=As configurações dos ramos não estão disponíveis quando o repositório está arquivado. settings.unarchive.button=Desarquivar repositório settings.unarchive.header=Desarquivar este repositório -settings.unarchive.text=Desarquivar o repositório irá restaurar a capacidade de receber cometimentos e empurrões, assim como novas questões e pedidos de integração. +settings.unarchive.text=Desarquivar o repositório irá restaurar a capacidade de receber cometimentos e envios, assim como novas questões e pedidos de integração. settings.unarchive.success=O repositório foi desarquivado com sucesso. settings.unarchive.error=Ocorreu um erro enquanto decorria o processo de desarquivar o repositório. Veja os registos para obter mais detalhes. settings.update_avatar_success=O avatar do repositório foi modificado. @@ -1863,12 +1864,12 @@ diff.download_diff=Descarregar ficheiro diff diff.show_split_view=Visualização em 2 colunas diff.show_unified_view=Visualização unificada diff.whitespace_button=Espaço em branco -diff.whitespace_show_everything=Mostrar todas as alterações +diff.whitespace_show_everything=Mostrar todas as modificações diff.whitespace_ignore_all_whitespace=Ignorar espaço em branco ao comparar linhas -diff.whitespace_ignore_amount_changes=Ignorar alterações na quantidade de espaço em branco -diff.whitespace_ignore_at_eol=Ignorar alterações do espaço em branco no fim das linhas -diff.stats_desc= %d ficheiros alterados com %d adições e %d eliminações -diff.stats_desc_file=%d alterações: %d adições e %d exclusões +diff.whitespace_ignore_amount_changes=Ignorar modificações na quantidade de espaço em branco +diff.whitespace_ignore_at_eol=Ignorar modificações do espaço em branco no fim das linhas +diff.stats_desc= %d ficheiros modificados com %d adições e %d eliminações +diff.stats_desc_file=%d modificações: %d adições e %d exclusões diff.bin=BIN diff.view_file=Ver ficheiro diff.file_before=Antes @@ -1877,7 +1878,7 @@ diff.file_image_width=Largura diff.file_image_height=Altura diff.file_byte_size=Tamanho diff.file_suppressed=A apresentação das diferenças no ficheiro foi suprimida por ser demasiado grande -diff.too_many_files=Alguns ficheiros não foram mostrados porque foram alterados demasiados ficheiros neste diff +diff.too_many_files=Alguns ficheiros não foram mostrados porque foram modificados demasiados ficheiros neste diff diff.comment.placeholder=Deixar um comentário diff.comment.markdown_info=A formatação com markdown é suportada. diff.comment.add_single_comment=Adicionar um único comentário @@ -1889,7 +1890,7 @@ diff.review.header=Submeter revisão diff.review.placeholder=Comentário da revisão diff.review.comment=Comentar diff.review.approve=Aprovar -diff.review.reject=Solicitar alterações +diff.review.reject=Solicitar modificações diff.committed_by=cometido por diff.protected=Protegido diff.image.side_by_side=Lado a Lado @@ -2050,9 +2051,9 @@ teams.can_create_org_repo_helper=Os membros podem criar novos repositórios na o teams.read_access=Acesso de leitura teams.read_access_helper=Os membros podem ver e clonar os repositórios da equipa. teams.write_access=Acesso de escrita -teams.write_access_helper=Os membros podem ler e empurrar para os repositórios da equipa. +teams.write_access_helper=Os membros podem ler e enviar para os repositórios da equipa. teams.admin_access=Acesso de administrador -teams.admin_access_helper=Os membros podem puxar de, e empurrar para os repositórios da equipa e adicionar colaboradores a esses repositórios. +teams.admin_access_helper=Os membros podem puxar de, e enviar para os repositórios da equipa e adicionar colaboradores a esses repositórios. teams.no_desc=Esta equipa não tem descrição teams.settings=Configurações teams.owners_permission_desc=Os proprietários têm acesso total a todos os repositórios e têm acesso de administrador à organização. @@ -2064,8 +2065,8 @@ teams.delete_team_title=Eliminar equipa teams.delete_team_desc=Eliminar uma equipa revoga o acesso dos seus membros ao repositório. Quer continuar? teams.delete_team_success=A equipa foi eliminada. teams.read_permission_desc=Esta equipa atribui acesso de leitura: os seus membros podem ver e clonar os repositórios da equipa. -teams.write_permission_desc=Esta equipa atribui acesso de escrita: os seus membros podem ler de e empurrar para os repositórios da equipa. -teams.admin_permission_desc=Esta equipa atribui o acesso de administração: os seus membros podem ler de, empurrar para e adicionar colaboradores aos repositórios da equipa. +teams.write_permission_desc=Esta equipa atribui acesso de escrita: os seus membros podem ler de, e enviar para os repositórios da equipa. +teams.admin_permission_desc=Esta equipa atribui o acesso de administração: os seus membros podem ler de, enviar para, e adicionar colaboradores aos repositórios da equipa. teams.create_repo_permission_desc=Adicionalmente, esta equipa atribui a permissão de criar repositórios: os seus membros podem criar novos repositórios na organização. teams.repositories=Repositórios da equipa teams.search_repo_placeholder=Procurar repositório… @@ -2082,8 +2083,8 @@ teams.specific_repositories_helper=Os membros só terão acesso a repositórios teams.all_repositories=Todos os repositórios teams.all_repositories_helper=A equipa tem acesso a todos os repositórios. Escolher isto irá adicionar todos os repositórios existentes à equipa. teams.all_repositories_read_permission_desc=Esta equipa atribui o acesso de leitura a todos os repositórios: os seus membros podem ver e clonar os repositórios. -teams.all_repositories_write_permission_desc=Esta equipa atribui o acesso de escrita a todos os repositórios: os seus membros podem ler de, e empurrar para os repositórios. -teams.all_repositories_admin_permission_desc=Esta equipa atribui o acesso de administração a todos os repositórios: os seus membros podem ler de, empurrar para e adicionar colaboradores aos repositórios. +teams.all_repositories_write_permission_desc=Esta equipa atribui o acesso de escrita a todos os repositórios: os seus membros podem ler de, e enviar para os repositórios. +teams.all_repositories_admin_permission_desc=Esta equipa atribui o acesso de administração a todos os repositórios: os seus membros podem ler de, enviar para, e adicionar colaboradores aos repositórios. [admin] dashboard=Painel de controlo @@ -2268,7 +2269,6 @@ auths.host=Servidor auths.port=Porto auths.bind_dn=Vincular DN auths.bind_password=Vincular senha -auths.bind_password_helper=Atenção: Esta senha é armazenada em texto simples. Use uma conta só de leitura, se possível. auths.user_base=Base de pesquisa de utilizador auths.user_dn=DN do utilizador auths.attribute_username=Atributo do nome de utilizador @@ -2569,7 +2569,7 @@ notices.delete_success=As notificações do sistema foram eliminadas. [action] create_repo=criou o repositório %s rename_repo=renomeou o repositório de %[1]s para %[3] -commit_repo=empurrou para %[3]s em %[4]s +commit_repo=enviou para %[3]s em %[4]s create_issue=`abriu a questão %s#%[2]s` close_issue=`fechou a questão %s#%[2]s` reopen_issue=`reabriu a questão %s#%[2]s` @@ -2580,7 +2580,7 @@ comment_issue=`comentou na questão %s#%[2]s` comment_pull=`comentou no pedido de integração %s#%[2]s` merge_pull_request=`executou a integração constante no pedido %s#%[2]s` transfer_repo=transferiu o repositório %s para %s -push_tag=empurrou a etiqueta %[2]s para %[3]s +push_tag=enviou a etiqueta %[2]s para %[3]s delete_tag=eliminou a etiqueta %[2]de %[3]s delete_branch=eliminou o ramo %[2]s de %[3]s compare_branch=Comparar @@ -2590,7 +2590,7 @@ mirror_sync_push=sincronizou cometimentos para %[3]s%[2]s para %[3]s do espelho mirror_sync_delete=sincronizou e eliminou a referência %[2]s em %[3]s do ficheiro approve_pull_request=`aprovou %s#%[2]s` -reject_pull_request=`sugeriu alterações para %s#%[2]s` +reject_pull_request=`sugeriu modificações para %s#%[2]s` publish_release=`lançou "%[4]s" à %[3]s` review_dismissed=`descartou a revisão de %[4]s para %[3]s#%[2]s` review_dismissed_reason=Motivo: diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index a8331f724b96d..4ee78c2fded58 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -2250,7 +2250,6 @@ auths.host=Сервер auths.port=Порт auths.bind_dn=Bind DN auths.bind_password=Привязать пароль -auths.bind_password_helper=Предупреждение: этот пароль хранится в виде простого текста. Используйте учетную запись только для чтения, если это возможно. auths.user_base=База для поиска пользователя auths.user_dn=DN пользователя auths.attribute_username=Атрибут Username diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index c67b4a1c97564..7e3ee1e9b92e8 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -1905,7 +1905,6 @@ auths.host=Värd auths.port=Port auths.bind_dn=Bind DN auths.bind_password=Bind Lösenord -auths.bind_password_helper=Varning: Detta lösenord lagras i klartext. Använd ett konto med endast läsrättigheter om möjligt. auths.user_base=Användarsökbas auths.user_dn=Användarnas DN auths.attribute_username=Användarnamnsattribut diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index dfa64cf4822de..efe2c5af5ac5b 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -2275,7 +2275,6 @@ auths.host=Sunucu auths.port=Bağlantı Noktası auths.bind_dn=Bağlama DN'i auths.bind_password=Bağlama Parolası -auths.bind_password_helper=Uyarı: Bu parola düz metin olarak saklanır. Mümkünse salt okunur bir hesap kullanın. auths.user_base=Kullanıcı Arama Tabanı auths.user_dn=Kullanıcı DN'i auths.attribute_username=Kullanıcı Adı Özelliği diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 7254784d4f6ab..dae0d646b26ae 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -2035,7 +2035,6 @@ auths.host=Хост auths.port=Порт auths.bind_dn=Прив'язати DN auths.bind_password=Прив'язати пароль -auths.bind_password_helper=Попередження: цей пароль зберігається у вигляді простого тексту. Використовуйте обліковий запис тільки для читання, якщо це можливо. auths.user_base=База пошуку користувачів auths.user_dn=DN користувача auths.attribute_username=Атрибут імені користувача diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index f098b3a45abb8..0d2cc88e93ece 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -1285,6 +1285,8 @@ issues.review.resolved_by=标记问题为已解决 issues.assignee.error=因为未知原因,并非所有的指派都成功。 issues.reference_issue.body=内容 +compare.compare_base=基准分支 +compare.compare_head=比较 pulls.desc=启用合并请求和代码评审。 pulls.new=创建合并请求 @@ -1526,7 +1528,7 @@ search.fuzzy=模糊 search.match=匹配 search.results=在 %s 中搜索 "%s" 的结果 -settings=仓库设置 +settings=设置 settings.desc=设置是你可以管理仓库设置的地方 settings.options=仓库 settings.collaboration=协作者 @@ -1535,7 +1537,7 @@ settings.collaboration.write=可写权限 settings.collaboration.read=可读权限 settings.collaboration.owner=所有者 settings.collaboration.undefined=未定义 -settings.hooks=管理 Web 钩子 +settings.hooks=Web 钩子 settings.githooks=管理 Git 钩子 settings.basic_settings=基本设置 settings.mirror_settings=镜像设置 @@ -1745,7 +1747,7 @@ settings.add_telegram_hook_desc=将 Telegram 集成到您的仓 settings.add_matrix_hook_desc=将 Matrix 集成到您的仓库中。 settings.add_msteams_hook_desc=将 Microsoft Teams 集成到您的仓库中。 settings.add_feishu_hook_desc=将 Feishu 集成到您的仓库中。 -settings.deploy_keys=管理部署密钥 +settings.deploy_keys=部署密钥 settings.add_deploy_key=添加部署密钥 settings.deploy_key_desc=部署密钥具有对仓库的只读拉取权限。 settings.is_writable=启用写权限 @@ -1759,7 +1761,7 @@ settings.add_key_success=部署密钥 '%s' 添加成功。 settings.deploy_key_deletion=删除部署密钥 settings.deploy_key_deletion_desc=删除部署密钥将吊销对此存储库的访问权限。继续? settings.deploy_key_deletion_success=部署密钥已删除。 -settings.branches=分支列表 +settings.branches=分支 settings.protected_branch=分支保护 settings.protected_branch_can_push=允许推吗? settings.protected_branch_can_push_yes=你可以推 @@ -1887,6 +1889,7 @@ diff.file_image_width=宽度 diff.file_image_height=高度 diff.file_byte_size=大小 diff.file_suppressed=文件差异内容过多而无法显示 +diff.file_suppressed_line_too_long=文件差异因一行或多行过长而隐藏 diff.too_many_files=部分文件因为文件数量过多而无法显示 diff.comment.placeholder=留下评论 diff.comment.markdown_info=支持使用Markdown格式。 @@ -2278,7 +2281,6 @@ auths.host=主机 auths.port=端口 auths.bind_dn=绑定 DN auths.bind_password=绑定密码 -auths.bind_password_helper=警告:密码将会被明文存储。如果可能请使用只读账号。 auths.user_base=用户搜索基准 auths.user_dn=用户 DN auths.attribute_username=用户名属性 @@ -2309,6 +2311,7 @@ auths.allowed_domains_helper=置空将允许所有域名,每个域名用逗号 auths.enable_tls=启用 TLS 加密 auths.skip_tls_verify=忽略 TLS 验证 auths.pam_service_name=PAM 服务名称 +auths.pam_email_domain=PAM 电子邮件域(可选) auths.oauth2_provider=OAuth2 提供程序 auths.oauth2_icon_url=图标 URL auths.oauth2_clientID=客户端 ID (键) @@ -2408,6 +2411,7 @@ config.db_path=数据库路径 config.service_config=服务配置 config.register_email_confirm=需要电子邮件确认注册 config.disable_register=禁止用户注册 +config.allow_only_internal_registration=只允许通过 Gitea 进行注册 config.allow_only_external_registration=仅允许通过外部服务注册 config.enable_openid_signup=启用 OpenID 自注册 config.enable_openid_signin=启用 OpenID 登录 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index bf58fecf14b61..8d73a43634da4 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -2280,7 +2280,6 @@ auths.host=主機地址 auths.port=連接埠 auths.bind_dn=Bind DN auths.bind_password=Bind 密碼 -auths.bind_password_helper=警告:此密碼以明文存儲。 請儘可能使用唯讀帳戶。 auths.user_base=用戶搜尋基準 auths.user_dn=用戶 DN auths.attribute_username=帳號屬性 diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 0876f3273cb50..5656730608151 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -888,7 +888,7 @@ func Routes() *web.Route { Post(reqToken(), mustNotBeArchived, bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) m.Group("/{index}", func() { m.Combo("").Get(repo.GetPullRequest). - Patch(reqToken(), reqRepoWriter(models.UnitTypePullRequests), bind(api.EditPullRequestOption{}), repo.EditPullRequest) + Patch(reqToken(), bind(api.EditPullRequestOption{}), repo.EditPullRequest) m.Get(".diff", repo.DownloadPullDiff) m.Get(".patch", repo.DownloadPullPatch) m.Post("/update", reqToken(), repo.UpdatePullRequest) diff --git a/routers/private/internal.go b/routers/private/internal.go index c6cc61fc29e21..9202e6721881d 100644 --- a/routers/private/internal.go +++ b/routers/private/internal.go @@ -55,6 +55,7 @@ func Routes() *web.Route { r.Post("/ssh/authorized_keys", AuthorizedPublicKeyByContent) r.Post("/ssh/{id}/update/{repoid}", UpdatePublicKeyInRepo) + r.Post("/ssh/log", bind(private.SSHLogOption{}), SSHLog) r.Post("/hook/pre-receive/{owner}/{repo}", bind(private.HookOptions{}), HookPreReceive) r.Post("/hook/post-receive/{owner}/{repo}", bind(private.HookOptions{}), HookPostReceive) r.Post("/hook/set-default-branch/{owner}/{repo}/{branch}", SetDefaultBranch) diff --git a/routers/private/ssh_log.go b/routers/private/ssh_log.go new file mode 100644 index 0000000000000..2f1793a0e0f4f --- /dev/null +++ b/routers/private/ssh_log.go @@ -0,0 +1,34 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package private + +import ( + "net/http" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/private" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" +) + +// SSHLog hook to response ssh log +func SSHLog(ctx *context.PrivateContext) { + if !setting.EnableSSHLog { + ctx.Status(http.StatusOK) + return + } + + opts := web.GetForm(ctx).(*private.SSHLogOption) + + if opts.IsError { + log.Error("ssh: %v", opts.Message) + ctx.Status(http.StatusOK) + return + } + + log.Debug("ssh: %v", opts.Message) + ctx.Status(http.StatusOK) +} diff --git a/routers/repo/http.go b/routers/repo/http.go index ef80f7ab02e7c..30d382b8ef18d 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -174,7 +174,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { return } - if ctx.IsBasicAuth { + if ctx.IsBasicAuth && ctx.Data["IsApiToken"] != true { _, err = models.GetTwoFactorByUID(ctx.User.ID) 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 diff --git a/services/mailer/mail.go b/services/mailer/mail.go index f22140c9f762e..ea3edaa90db6e 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -11,6 +11,7 @@ import ( "html/template" "mime" "regexp" + "strconv" "strings" texttmpl "text/template" @@ -174,7 +175,7 @@ func SendCollaboratorMail(u, doer *models.User, repo *models.Repository) { SendAsync(msg) } -func composeIssueCommentMessages(ctx *mailCommentContext, lang string, tos []string, fromMention bool, info string) ([]*Message, error) { +func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipients []*models.User, fromMention bool, info string) ([]*Message, error) { var ( subject string link string @@ -265,9 +266,9 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, tos []str } // Make sure to compose independent messages to avoid leaking user emails - msgs := make([]*Message, 0, len(tos)) - for _, to := range tos { - msg := NewMessageFrom([]string{to}, ctx.Doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String()) + msgs := make([]*Message, 0, len(recipients)) + for _, recipient := range recipients { + msg := NewMessageFrom([]string{recipient.Email}, ctx.Doer.DisplayName(), setting.MailService.FromEmail, subject, mailBody.String()) msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info) // Set Message-ID on first message so replies know what to reference @@ -277,12 +278,51 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, tos []str msg.SetHeader("In-Reply-To", "<"+ctx.Issue.ReplyReference()+">") msg.SetHeader("References", "<"+ctx.Issue.ReplyReference()+">") } + + for key, value := range generateAdditionalHeaders(ctx, actType, recipient) { + msg.SetHeader(key, value) + } + msgs = append(msgs, msg) } return msgs, nil } +func generateAdditionalHeaders(ctx *mailCommentContext, reason string, recipient *models.User) map[string]string { + repo := ctx.Issue.Repo + + return map[string]string{ + // https://datatracker.ietf.org/doc/html/rfc2919 + "List-ID": fmt.Sprintf("%s <%s.%s.%s>", repo.FullName(), repo.Name, repo.OwnerName, setting.Domain), + + // https://datatracker.ietf.org/doc/html/rfc2369 + "List-Archive": fmt.Sprintf("<%s>", repo.HTMLURL()), + //"List-Post": https://github.com/go-gitea/gitea/pull/13585 + //"List-Unsubscribe": https://github.com/go-gitea/gitea/issues/10808, https://github.com/go-gitea/gitea/issues/13283 + + "X-Gitea-Reason": reason, + "X-Gitea-Sender": ctx.Doer.DisplayName(), + "X-Gitea-Recipient": recipient.DisplayName(), + "X-Gitea-Recipient-Address": recipient.Email, + "X-Gitea-Repository": repo.Name, + "X-Gitea-Repository-Path": repo.FullName(), + "X-Gitea-Repository-Link": repo.HTMLURL(), + "X-Gitea-Issue-ID": strconv.FormatInt(ctx.Issue.Index, 10), + "X-Gitea-Issue-Link": ctx.Issue.HTMLURL(), + + "X-GitHub-Reason": reason, + "X-GitHub-Sender": ctx.Doer.DisplayName(), + "X-GitHub-Recipient": recipient.DisplayName(), + "X-GitHub-Recipient-Address": recipient.Email, + + "X-GitLab-NotificationReason": reason, + "X-GitLab-Project": repo.Name, + "X-GitLab-Project-Path": repo.FullName(), + "X-GitLab-Issue-IID": strconv.FormatInt(ctx.Issue.Index, 10), + } +} + func sanitizeSubject(subject string) string { runes := []rune(strings.TrimSpace(subjectRemoveSpaces.ReplaceAllLiteralString(subject, " "))) if len(runes) > mailMaxSubjectRunes { @@ -294,9 +334,9 @@ func sanitizeSubject(subject string) string { // SendIssueAssignedMail composes and sends issue assigned email func SendIssueAssignedMail(issue *models.Issue, doer *models.User, content string, comment *models.Comment, recipients []*models.User) error { - langMap := make(map[string][]string) + langMap := make(map[string][]*models.User) for _, user := range recipients { - langMap[user.Language] = append(langMap[user.Language], user.Email) + langMap[user.Language] = append(langMap[user.Language], user) } for lang, tos := range langMap { diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go index bb541d27a091a..cf5265872b3fb 100644 --- a/services/mailer/mail_issue.go +++ b/services/mailer/mail_issue.go @@ -116,7 +116,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*models.User, visite checkUnit = models.UnitTypePullRequests } - langMap := make(map[string][]string) + langMap := make(map[string][]*models.User) for _, user := range users { // At this point we exclude: // user that don't have all mails enabled or users only get mail on mention and this is one ... @@ -138,7 +138,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*models.User, visite continue } - langMap[user.Language] = append(langMap[user.Language], user.Email) + langMap[user.Language] = append(langMap[user.Language], user) } for lang, receivers := range langMap { diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index 813e51c0d215b..0a9112f3be59d 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -39,7 +39,7 @@ const bodyTpl = ` ` -func TestComposeIssueCommentMessage(t *testing.T) { +func prepareMailerTest(t *testing.T) (doer *models.User, repo *models.Repository, issue *models.Issue, comment *models.Comment) { assert.NoError(t, models.PrepareTestDatabase()) var mailService = setting.Mailer{ From: "test@gitea.com", @@ -48,18 +48,24 @@ func TestComposeIssueCommentMessage(t *testing.T) { setting.MailService = &mailService setting.Domain = "localhost" - doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) - repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository) - issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue) - comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment) + doer = models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + repo = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository) + issue = models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue) + assert.NoError(t, issue.LoadRepo()) + comment = models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment) + return +} + +func TestComposeIssueCommentMessage(t *testing.T) { + doer, _, issue, comment := prepareMailerTest(t) stpl := texttmpl.Must(texttmpl.New("issue/comment").Parse(subjectTpl)) btpl := template.Must(template.New("issue/comment").Parse(bodyTpl)) InitMailRender(stpl, btpl) - tos := []string{"test@gitea.com", "test2@gitea.com"} + recipients := []*models.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(&mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue, - Content: "test body", Comment: comment}, "en-US", tos, false, "issue comment") + Content: "test body", Comment: comment}, "en-US", recipients, false, "issue comment") assert.NoError(t, err) assert.Len(t, msgs, 2) gomailMsg := msgs[0].ToMessage() @@ -76,25 +82,15 @@ func TestComposeIssueCommentMessage(t *testing.T) { } func TestComposeIssueMessage(t *testing.T) { - assert.NoError(t, models.PrepareTestDatabase()) - var mailService = setting.Mailer{ - From: "test@gitea.com", - } - - setting.MailService = &mailService - setting.Domain = "localhost" - - doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) - repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository) - issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue) + doer, _, issue, _ := prepareMailerTest(t) stpl := texttmpl.Must(texttmpl.New("issue/new").Parse(subjectTpl)) btpl := template.Must(template.New("issue/new").Parse(bodyTpl)) InitMailRender(stpl, btpl) - tos := []string{"test@gitea.com", "test2@gitea.com"} + recipients := []*models.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}} msgs, err := composeIssueCommentMessages(&mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue, - Content: "test body"}, "en-US", tos, false, "issue create") + Content: "test body"}, "en-US", recipients, false, "issue create") assert.NoError(t, err) assert.Len(t, msgs, 2) @@ -111,18 +107,8 @@ func TestComposeIssueMessage(t *testing.T) { } func TestTemplateSelection(t *testing.T) { - assert.NoError(t, models.PrepareTestDatabase()) - var mailService = setting.Mailer{ - From: "test@gitea.com", - } - - setting.MailService = &mailService - setting.Domain = "localhost" - - doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) - repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository) - issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue) - tos := []string{"test@gitea.com"} + doer, repo, issue, comment := prepareMailerTest(t) + recipients := []*models.User{{Name: "Test", Email: "test@gitea.com"}} stpl := texttmpl.Must(texttmpl.New("issue/default").Parse("issue/default/subject")) texttmpl.Must(stpl.New("issue/new").Parse("issue/new/subject")) @@ -146,38 +132,26 @@ func TestTemplateSelection(t *testing.T) { } msg := testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue, - Content: "test body"}, tos, false, "TestTemplateSelection") + Content: "test body"}, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/new/subject", "issue/new/body") - comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment) msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue, - Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection") + Content: "test body", Comment: comment}, recipients, false, "TestTemplateSelection") expect(t, msg, "issue/default/subject", "issue/default/body") pull := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 2, Repo: repo, Poster: doer}).(*models.Issue) comment = models.AssertExistsAndLoadBean(t, &models.Comment{ID: 4, Issue: pull}).(*models.Comment) msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: pull, Doer: doer, ActionType: models.ActionCommentPull, - Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection") + Content: "test body", Comment: comment}, recipients, false, "TestTemplateSelection") expect(t, msg, "pull/comment/subject", "pull/comment/body") msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCloseIssue, - Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection") + Content: "test body", Comment: comment}, recipients, false, "TestTemplateSelection") expect(t, msg, "Re: [user2/repo1] issue1 (#1)", "issue/close/body") } func TestTemplateServices(t *testing.T) { - assert.NoError(t, models.PrepareTestDatabase()) - var mailService = setting.Mailer{ - From: "test@gitea.com", - } - - setting.MailService = &mailService - setting.Domain = "localhost" - - doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) - repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository) - issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue) - comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment) + doer, _, issue, comment := prepareMailerTest(t) assert.NoError(t, issue.LoadRepo()) expect := func(t *testing.T, issue *models.Issue, comment *models.Comment, doer *models.User, @@ -187,9 +161,9 @@ func TestTemplateServices(t *testing.T) { btpl := template.Must(template.New("issue/default").Parse(tplBody)) InitMailRender(stpl, btpl) - tos := []string{"test@gitea.com"} + recipients := []*models.User{{Name: "Test", Email: "test@gitea.com"}} msg := testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: actionType, - Content: "test body", Comment: comment}, tos, fromMention, "TestTemplateServices") + Content: "test body", Comment: comment}, recipients, fromMention, "TestTemplateServices") subject := msg.ToMessage().GetHeader("Subject") msgbuf := new(bytes.Buffer) @@ -219,9 +193,38 @@ func TestTemplateServices(t *testing.T) { "//Re: //") } -func testComposeIssueCommentMessage(t *testing.T, ctx *mailCommentContext, tos []string, fromMention bool, info string) *Message { - msgs, err := composeIssueCommentMessages(ctx, "en-US", tos, fromMention, info) +func testComposeIssueCommentMessage(t *testing.T, ctx *mailCommentContext, recipients []*models.User, fromMention bool, info string) *Message { + msgs, err := composeIssueCommentMessages(ctx, "en-US", recipients, fromMention, info) assert.NoError(t, err) assert.Len(t, msgs, 1) return msgs[0] } + +func TestGenerateAdditionalHeaders(t *testing.T) { + doer, _, issue, _ := prepareMailerTest(t) + + ctx := &mailCommentContext{Issue: issue, Doer: doer} + recipient := &models.User{Name: "Test", Email: "test@gitea.com"} + + headers := generateAdditionalHeaders(ctx, "dummy-reason", recipient) + + expected := map[string]string{ + "List-ID": "user2/repo1 ", + "List-Archive": "", + "X-Gitea-Reason": "dummy-reason", + "X-Gitea-Sender": "< Ur Tw ><", + "X-Gitea-Recipient": "Test", + "X-Gitea-Recipient-Address": "test@gitea.com", + "X-Gitea-Repository": "repo1", + "X-Gitea-Repository-Path": "user2/repo1", + "X-Gitea-Repository-Link": "https://try.gitea.io/user2/repo1", + "X-Gitea-Issue-ID": "1", + "X-Gitea-Issue-Link": "https://try.gitea.io/user2/repo1/issues/1", + } + + for key, value := range expected { + if assert.Contains(t, headers, key) { + assert.Equal(t, value, headers[key]) + } + } +} diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl index e4d7a2e1e1fb2..d825cd7d12de6 100644 --- a/templates/admin/auth/edit.tmpl +++ b/templates/admin/auth/edit.tmpl @@ -53,7 +53,6 @@
-

{{.i18n.Tr "admin.auths.bind_password_helper"}}

{{end}}
diff --git a/templates/admin/auth/source/ldap.tmpl b/templates/admin/auth/source/ldap.tmpl index 584538f53bc91..1cbcb2fd415ea 100644 --- a/templates/admin/auth/source/ldap.tmpl +++ b/templates/admin/auth/source/ldap.tmpl @@ -28,7 +28,6 @@
-

{{.i18n.Tr "admin.auths.bind_password_helper"}}

diff --git a/templates/explore/code.tmpl b/templates/explore/code.tmpl index 6332413a173a6..8cc1b71a7ad0a 100644 --- a/templates/explore/code.tmpl +++ b/templates/explore/code.tmpl @@ -50,7 +50,7 @@ {{.}} {{end}} -
    {{.FormattedLines | Safe}}
+ {{.FormattedLines | Safe}} diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 582b66d5db6e5..d8678c95c6e31 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -117,7 +117,7 @@
-
+
{{if $file.IsBin}}
{{$.i18n.Tr "repo.diff.bin_not_shown"}}
{{else}} @@ -131,7 +131,7 @@ {{end}}
{{if or $isImage $isCsv}} -
+
{{if $isImage}} {{template "repo/diff/image_diff" dict "file" . "root" $}} diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl index 6e39fbe854991..c55da8576e185 100644 --- a/templates/repo/diff/comments.tmpl +++ b/templates/repo/diff/comments.tmpl @@ -3,7 +3,7 @@ {{ $createdStr:= TimeSinceUnix .CreatedUnix $.root.Lang }}
{{if .OriginalAuthor }} - + {{else}} {{avatar .Poster}} diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl index 897d297d37cb5..3f4a13570f68d 100644 --- a/templates/repo/issue/milestone_issues.tmpl +++ b/templates/repo/issue/milestone_issues.tmpl @@ -2,14 +2,9 @@
{{template "repo/header" .}}
-
+

{{.Milestone.Name}}

-
- {{.Milestone.RenderedContent|Str2html}} -
-
-
{{if not .Repository.IsArchived}}
@@ -20,6 +15,11 @@
{{end}}
+
+
+ {{.Milestone.RenderedContent|Str2html}} +
+
{{ $closedDate:= TimeSinceUnix .Milestone.ClosedDateUnix $.Lang }} diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index e353d71ee969a..35c7cdd7a2c30 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -13,7 +13,7 @@
{{if .Issue.OriginalAuthor }} - + {{else}} {{avatar .Issue.Poster}} diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index e02f3ddc894c4..77757207cf2e9 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -13,7 +13,7 @@ {{if eq .Type 0}}
{{if .OriginalAuthor }} - + {{else}} {{avatar .Poster}} diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 22e9f34e5dfce..2f4295726658e 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -6,12 +6,12 @@
+
    {{.FormattedLines | Safe}}
{{.FormattedLines | Safe}}
diff --git a/templates/repo/settings/branches.tmpl b/templates/repo/settings/branches.tmpl index fbe9a7463e5e2..ccf6abbb81c01 100644 --- a/templates/repo/settings/branches.tmpl +++ b/templates/repo/settings/branches.tmpl @@ -35,7 +35,7 @@ {{end}}
- +
{{end}} diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index e3a52a887083a..8c73f1252b85f 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -112,7 +112,7 @@ {{if $.Permission.CanRead $.UnitTypeIssues}} -