diff --git a/CHANGELOG.md b/CHANGELOG.md
index a28e6130c..c1c8d4d30 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,11 +4,32 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io).
-## [1.4.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.4.0-rc1) - 2018-01-31
+## [1.4.1](https://github.com/go-gitea/gitea/releases/tag/v1.4.1) - 2018-05-03
+* BREAKING
+ * Add "error" as reserved username (#3882) (#3886)
+* SECURITY
+ * Do not allow inactive users to access repositories using private key (#3887) (#3889)
+ * Fix path cleanup in file editor, when initilizing new repository and LFS oids (#3871) (#3873)
+ * Remove unnecessary allowed safe HTML (#3778) (#3779)
+ * Correctly check http git access rights for reverse proxy authorized users (#3721) (#3743)
+* BUGFIXES
+ * Fix to use only needed columns from tables to get repository git paths (#3870) (#3883)
+ * Fix GPG expire time display when time is zero (#3584) (#3884)
+ * Fix to update only issue last update time when adding a comment (#3855) (#3860)
+ * Fix repository star count after deleting user (#3781) (#3783)
+ * Use the active branch for the code tab (#3720) (#3776)
+ * Set default branch name on first push (#3715) (#3723)
+ * Show clipboard button if disable HTTP of git protocol (#3773) (#3774)
+
+## [1.4.0](https://github.com/go-gitea/gitea/releases/tag/v1.4.0) - 2018-03-25
* BREAKING
* Drop deprecated GOGS\_WORK\_DIR use (#2946)
* Fix API status code for hook creation (#2814)
* SECURITY
+ * Escape branch name in dropdown menu (#3691) (#3692)
+ * Refactor and simplify to correctly validate redirect to URL (#3674) (#3676)
+ * Fix escaping changed title in comments (#3530) (#3534)
+ * Escape search query (#3486) (#3488)
* Sanitize logs for mirror sync (#3057)
* FEATURE
* Serve .patch and .diff for pull requests (#3305, #3293)
@@ -24,6 +45,17 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Add dingtalk webhook (#2777)
* Responsive view (#2750)
* BUGFIXES
+ * Fix wiki inter-links with spaces (#3560) (#3632)
+ * Fix query protected branch bug (#3563) (#3571)
+ * Fix remove team member issue (#3566) (#3570)
+ * Fix the protected branch panic issue (#3567) (#3569)
+ * If Mirrors repository no content is fetched, updated time should not be changed (#3551) (#3565)
+ * Bug fix for mirrored repository releases sorted (#3522) (#3555)
+ * Add issue closed time column to fix activity closed issues list (#3537) (#3540)
+ * Update markbates/goth library to support OAuth2 with new dropbox API (#3533) (#3539)
+ * Fixes missing avatars in offline mode (#3471) (#3477)
+ * Fix synchronization bug in repo indexer (#3455) (#3461)
+ * Fix rendering of wiki page list if wiki repo contains other files (#3454) (#3463)
* Fix webhook X-GitHub-* headers casing for better compatibility (#3429)
* Add content type and doctype to requests made with go-get (#3426, #3423)
* Fix SQL type error for webhooks (#3424)
diff --git a/integrations/user_test.go b/integrations/user_test.go
index 0b59663a4..7ff986d54 100644
--- a/integrations/user_test.go
+++ b/integrations/user_test.go
@@ -27,9 +27,10 @@ func TestRenameUsername(t *testing.T) {
session := loginUser(t, "user2")
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
- "_csrf": GetCSRF(t, session, "/user/settings"),
- "name": "newUsername",
- "email": "user2@example.com",
+ "_csrf": GetCSRF(t, session, "/user/settings"),
+ "name": "newUsername",
+ "email": "user2@example.com",
+ "language": "en-us",
})
session.MakeRequest(t, req, http.StatusFound)
@@ -81,9 +82,10 @@ func TestRenameReservedUsername(t *testing.T) {
for _, reservedUsername := range reservedUsernames {
t.Logf("Testing username %s", reservedUsername)
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
- "_csrf": GetCSRF(t, session, "/user/settings"),
- "name": reservedUsername,
- "email": "user2@example.com",
+ "_csrf": GetCSRF(t, session, "/user/settings"),
+ "name": reservedUsername,
+ "email": "user2@example.com",
+ "language": "en-us",
})
resp := session.MakeRequest(t, req, http.StatusFound)
diff --git a/integrations/xss_test.go b/integrations/xss_test.go
index d71c680d6..d93d0ec03 100644
--- a/integrations/xss_test.go
+++ b/integrations/xss_test.go
@@ -24,6 +24,7 @@ func TestXSSUserFullName(t *testing.T) {
"name": user.Name,
"full_name": fullName,
"email": user.Email,
+ "language": "en-us",
})
session.MakeRequest(t, req, http.StatusFound)
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 522086a52..aa9dd1310 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -178,6 +178,8 @@ var migrations = []Migration{
NewMigration("add size column for attachments", addSizeToAttachment),
// v62 -> v63
NewMigration("add last used passcode column for TOTP", addLastUsedPasscodeTOTP),
+ // v63 -> v64
+ NewMigration("add language column for user setting", addLanguageSetting),
}
// Migrate database to current version
diff --git a/models/migrations/v63.go b/models/migrations/v63.go
new file mode 100644
index 000000000..6e7d940ed
--- /dev/null
+++ b/models/migrations/v63.go
@@ -0,0 +1,23 @@
+// Copyright 2018 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 migrations
+
+import (
+ "fmt"
+
+ "github.com/go-xorm/xorm"
+)
+
+func addLanguageSetting(x *xorm.Engine) error {
+ type User struct {
+ Language string `xorm:"VARCHAR(5)"`
+ }
+
+ if err := x.Sync2(new(User)); err != nil {
+ return fmt.Errorf("Sync2: %v", err)
+ }
+
+ return nil
+}
diff --git a/models/user.go b/models/user.go
index 2167e269b..106d79ffc 100644
--- a/models/user.go
+++ b/models/user.go
@@ -94,6 +94,7 @@ type User struct {
Website string
Rands string `xorm:"VARCHAR(10)"`
Salt string `xorm:"VARCHAR(10)"`
+ Language string `xorm:"VARCHAR(5)"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
@@ -185,6 +186,7 @@ func (u *User) APIFormat() *api.User {
FullName: u.FullName,
Email: u.getEmail(),
AvatarURL: u.AvatarLink(),
+ Language: u.Language,
}
}
diff --git a/modules/auth/user_form.go b/modules/auth/user_form.go
index d913822a8..956ebd944 100644
--- a/modules/auth/user_form.go
+++ b/modules/auth/user_form.go
@@ -109,6 +109,7 @@ type UpdateProfileForm struct {
KeepEmailPrivate bool
Website string `binding:"ValidUrl;MaxSize(255)"`
Location string `binding:"MaxSize(50)"`
+ Language string `binding:"Size(5)"`
}
// Validate validates the fields
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 6348a275a..379da8aab 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -331,6 +331,7 @@ change_username = Your username has been changed.
change_username_prompt = Note: username changes also change your account URL.
continue = Continue
cancel = Cancel
+language = Language
lookup_avatar_by_mail = Look Up Avatar by Email Address
federated_avatar_lookup = Federated Avatar Lookup
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index 4d0c7f7be..d0de25b2d 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -748,9 +748,9 @@ issues.due_date_form_update=Modificar data limite
issues.due_date_form_remove=Remover data limite
issues.due_date_not_writer=Você precisa ter pelo menos permissão de escrita neste repositório para atualizar a data limite desta issue.
issues.due_date_not_set=Data limite não informada.
-issues.due_date_added=adicionou a data limite %s %s
-issues.due_date_modified=modificou a data limite para %s %s %s
-issues.due_date_remove=removeu a data limite %s %s
+issues.due_date_added=adicionou a data limite %s à %s
+issues.due_date_modified=modificou a data limite para %s ao invés de %s à %s
+issues.due_date_remove=removeu a data limite %s à %s
issues.due_date_overdue=Em atraso
pulls.desc=Habilitar solicitações de merge e revisões de código.
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index d19bb43dd..d297a94a5 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -28,6 +28,7 @@ password=Пароль
re_type=Введіть пароль ще раз
captcha=CAPTCHA
twofa=Двофакторна авторизація
+twofa_scratch=Двофакторний одноразовий пароль
passcode=Код доступу
repository=Репозиторій
@@ -39,6 +40,7 @@ new_mirror=Нове дзеркало
new_fork=Новий репозиторій - копія
new_org=Нова організація
manage_org=Керування організаціями
+admin_panel=Панель Адміністратора
account_settings=Налаштування облікового запису
settings=Налаштування
your_profile=Профіль
@@ -53,7 +55,7 @@ forks=Форки
activities=Дії
pull_requests=Запити на злиття
-issues=Питання
+issues=Проблеми
cancel=Відміна
@@ -141,7 +143,7 @@ active_your_account=Активувати обліковий запис
prohibit_login=Вхід заборонений
prohibit_login_desc=Вхід для вашого профілю був заборонений, будь ласка, зв'яжіться з адміністратором сайту.
resent_limit_prompt=Вибачте, ви вже запросили активацію по електронній пошті нещодавно. Будь ласка, зачекайте 3 хвилини, а потім спробуйте ще раз.
-has_unconfirmed_mail=Привіт %s, у вас є непідтвердженими адреси (%s). Якщо ви не отримали підтвердження електронною поштою або треба відправити нове, будь ласка, натисніть на кнопку нижче.
+has_unconfirmed_mail=Привіт %s, у вас є непідтверджена електронна адреса (%s ). Якщо ви не отримали електронний лист із підтвердженням або вам потрібно надіслати новий, натисніть на кнопку нижче.
resend_mail=Натисніть тут, щоб вислати лист активації знову
email_not_associate=Ця електронна пошта не пов'язана ні з одним обліковим записом.
send_reset_mail=Натисніть сюди, щоб відправити лист для скидання пароля
@@ -250,11 +252,13 @@ cancel=Відміна
federated_avatar_lookup=Знайти зовнішній аватар
enable_custom_avatar=Увімкнути користувацькі аватари
choose_new_avatar=Оберіть новий аватар
+update_avatar=Оновити аватар
delete_current_avatar=Видалити поточний аватар
change_password=Оновити пароль
old_password=Поточний пароль
new_password=Новий пароль
+retype_new_password=Введіть новий пароль ще раз
emails=Адреса електронної пошти
email_desc=Ваша основна адреса електронної пошти використовуватиметься для сповіщення та інших операцій.
@@ -304,6 +308,7 @@ owner=Власник
repo_name=Назва репозиторію
visibility=Видимість
visiblity_helper=Зробити репозиторій приватним
+clone_helper=Потрібна допомога у клонуванні? Відвідайте Допомогу.
fork_repo=Форкнути репозиторій
fork_from=Форк з
repo_desc=Опис
@@ -351,7 +356,7 @@ tree=Дерево
filter_branch_and_tag=Фільтрувати гілку або тег
branches=Гілки
tags=Теги
-issues=Питання
+issues=Проблеми
pulls=Запити на злиття
labels=Мітки
milestones=Етап
@@ -362,17 +367,18 @@ file_raw=Raw
file_history=Історія
file_view_raw=Перегляд Raw
file_permalink=Постійне посилання
+stored_lfs=Збережено з Git LFS
editor.new_file=Новий файл
editor.upload_file=Завантажити файл
-editor.edit_file=Редагування файла
+editor.edit_file=Редагувати файл
editor.preview_changes=Попередній перегляд змін
editor.edit_this_file=Редагування файла
editor.delete_this_file=Видалити файл
editor.name_your_file=Дайте назву файлу…
editor.or=або
editor.cancel_lower=Скасувати
-editor.commit_changes=Зафіксувати зміни
+editor.commit_changes=Закомітити зміни
editor.add_tmpl=Додати '%s/'
editor.add=Додати '%s'
editor.update=Оновити '%s'
@@ -392,7 +398,7 @@ commits.older=Давніше
commits.newer=Новіше
-issues.new=Нове обговорення
+issues.new=Нова Проблема
issues.new.labels=Мітки
issues.new.no_label=Без Мітки
issues.new.clear_labels=Очистити мітки
@@ -401,9 +407,10 @@ issues.new.no_milestone=Етап відсутній
issues.new.clear_milestone=Очистити етап
issues.new.open_milestone=Активні етапи
issues.new.closed_milestone=Закриті етапи
-issues.new.assignee=Призначено
-issues.new.clear_assignee=Прибрати відповідального
-issues.new.no_assignee=Немає відповідального
+issues.new.assignee=Виконавець
+issues.new.clear_assignee=Прибрати виконавеця
+issues.new.no_assignee=Немає виконавеця
+issues.create=Створити Проблему
issues.new_label=Нова мітка
issues.new_label_placeholder=Назва мітки
issues.new_label_desc_placeholder=Опис
@@ -414,11 +421,14 @@ issues.deleted_milestone=`(видалено)`
issues.open_tab=%d відкрито
issues.close_tab=%d закрито
issues.filter_label=Мітка
+issues.filter_label_no_select=Всі мітки
issues.filter_milestone=Етап
issues.filter_milestone_no_select=Всі етапи
-issues.filter_assignee=Відповідальний
+issues.filter_assignee=Виконавець
+issues.filter_assginee_no_select=Всі виконавеці
issues.filter_type=Тип
-issues.filter_type.all_issues=Всі проблемы
+issues.filter_type.all_issues=Всі проблеми
+issues.filter_type.assigned_to_you=Призначене вам
issues.filter_type.created_by_you=Створено вами
issues.filter_type.mentioning_you=Вас згадано
issues.filter_sort=Сортувати
@@ -433,8 +443,8 @@ issues.action_close=Закрити
issues.action_label=Мітка
issues.action_milestone=Етап
issues.action_milestone_no_select=Етап відсутній
-issues.action_assignee=Відповідальний
-issues.action_assignee_no_select=Немає відповідального
+issues.action_assignee=Виконавець
+issues.action_assignee_no_select=Немає виконавеця
issues.opened_by=%[1]s відкрито %[3]s
issues.opened_by_fake=%[1]s відкрито %[2]s
issues.previous=Попередній
@@ -448,6 +458,7 @@ issues.no_content=Тут ще немає жодного змісту.
issues.close_issue=Закрити
issues.close_comment_issue=Прокоментувати і закрити
issues.reopen_issue=Відкрити знову
+issues.reopen_comment_issue=Прокоментувати та відкрити знову
issues.create_comment=Коментар
issues.closed_at=`закрито %[2]s`
issues.reopened_at=`повторно відкрито %[2]s`
@@ -459,11 +470,14 @@ issues.edit=Редагувати
issues.cancel=Відміна
issues.save=Зберегти
issues.label_title=Назва мітки
+issues.label_description=Опис мітки
issues.label_color=Колір мітки
issues.label_count=%d міток
-issues.label_open_issues=%d відкритих питань
+issues.label_open_issues=%d відкритих проблем
issues.label_edit=Редагувати
issues.label_delete=Видалити
+issues.label_modify=Редагувати мітку
+issues.label_deletion=Видалити мітку
issues.label.filter_sort.alphabetically=За абеткою
issues.label.filter_sort.reverse_alphabetically=Зворотною абеткою
issues.label.filter_sort.by_size=Розмір
@@ -482,6 +496,8 @@ issues.cancel_tracking=Відміна
pulls.new=Новий запит на злиття
pulls.compare_changes=Новий запит на злиття
+pulls.compare_base=злити в
+pulls.compare_compare=pull з
pulls.filter_branch=Фільтр по гілці
pulls.no_results=Результатів не знайдено.
pulls.create=Створити запит на злиття
@@ -510,6 +526,7 @@ milestones.modify=Оновити етап
wiki=Wiki
+wiki.welcome=Ласкаво просимо до Wiki.
wiki.page=Сторінка
wiki.filter_page=Фільтр сторінок
wiki.new_page=Сторінка
@@ -528,14 +545,18 @@ activity.period.weekly=1 тиждень
activity.period.monthly=1 місяць
activity.overview=Огляд
activity.active_prs_count_n=%d Активні запити на злиття
-activity.merged_prs_count_1=Об'єднати запит на злиття
-activity.merged_prs_count_n=Об'єднати запити на злиття
+activity.merged_prs_count_1=Злитий запит на злиття
+activity.merged_prs_count_n=Злиті запити на злиття
activity.merged_prs_label=Злито
+activity.active_issues_count_1=%d Активна проблема
+activity.active_issues_count_n=%d Активні проблеми
+activity.closed_issues_count_1=Закрита проблема
activity.closed_issues_count_n=Закриті проблеми
+activity.title.issues_1=%d Проблема
activity.title.issues_n=%d Проблеми
activity.closed_issue_label=Закриті
-activity.new_issues_count_1=Нове обговорення
-activity.new_issues_count_n=Нове обговорення
+activity.new_issues_count_1=Нова Проблема
+activity.new_issues_count_n=%d Проблем
activity.new_issue_label=Відкриті
activity.unresolved_conv_label=Відкрити
activity.published_release_label=Опубліковано
@@ -566,6 +587,7 @@ settings.tracker_issue_style.numeric=Цифровий
settings.tracker_issue_style.alphanumeric=Буквено-цифровий
settings.danger_zone=Небезпечна зона
settings.new_owner_has_same_repo=Новий власник вже має репозиторій з такою назвою. Будь ласка, виберіть інше ім'я.
+settings.transfer=Переказати новому власнику
settings.delete=Видалити цей репозиторій
settings.delete_notices_1=- Цю операцію НЕ МОЖНА відмінити.
settings.transfer_owner=Новий власник
@@ -604,6 +626,7 @@ settings.is_writable=Включити доступ для запису
settings.title=Заголовок
settings.deploy_key_content=Зміст
settings.branches=Гілки
+settings.protected_branch=Захист гілки
settings.protected_branch_can_push=Дозволити push?
settings.protected_branch_can_push_yes=Ви можете виконувати push
settings.protected_branch_can_push_no=Ви не можете виконувати push
@@ -628,14 +651,22 @@ release.ahead=%d комітів %s після цього рел
release.tag_name=Назва тегу
release.target=Ціль
release.title=Заголовок
+release.content=Зміст
release.preview=Переглянути
release.loading=Завантаження…
+release.prerelease_desc=Позначити як пре-реліз
release.cancel=Відміна
+release.publish=Опублікувати реліз
+release.save_draft=Зберегти чернетку
release.edit_release=Оновити реліз
release.delete_release=Видалити реліз
release.deletion=Видалити реліз
+release.downloads=Завантажити
branch.delete_head=Видалити
+branch.delete=Видалити гілку '%s'
+branch.delete_html=Видалити гілку
+branch.deleted_by=Видалено %s
topic.done=Готово
@@ -643,6 +674,7 @@ topic.done=Готово
org_name_holder=Назва організації
org_full_name_holder=Повна назва організації
repo_updated=Оновлено
+people=Учасники
teams=Команди
lower_members=учасники
lower_repositories=репозиторії
diff --git a/public/swagger.v1.json b/public/swagger.v1.json
index b639d3ffe..0b1f4793b 100644
--- a/public/swagger.v1.json
+++ b/public/swagger.v1.json
@@ -7395,6 +7395,11 @@
"format": "int64",
"x-go-name": "ID"
},
+ "language": {
+ "description": "User locale",
+ "type": "string",
+ "x-go-name": "Language"
+ },
"login": {
"description": "the user's username",
"type": "string",
diff --git a/routers/user/auth.go b/routers/user/auth.go
index 4249f9e5f..2a5cb8e4b 100644
--- a/routers/user/auth.go
+++ b/routers/user/auth.go
@@ -339,6 +339,18 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR
ctx.Session.Set("uid", u.ID)
ctx.Session.Set("uname", u.Name)
+ // Language setting of the user overwrites the one previously set
+ // If the user does not have a locale set, we save the current one.
+ if len(u.Language) == 0 {
+ u.Language = ctx.Locale.Language()
+ if err := models.UpdateUserCols(u, "language"); err != nil {
+ log.Error(4, fmt.Sprintf("Error updating user language [user: %d, locale: %s]", u.ID, u.Language))
+ return
+ }
+ }
+
+ ctx.SetCookie("lang", u.Language, nil, setting.AppSubURL)
+
// Clear whatever CSRF has right now, force to generate a new one
ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL)
@@ -704,6 +716,7 @@ func SignOut(ctx *context.Context) {
ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubURL)
ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubURL)
ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL)
+ ctx.SetCookie("lang", "", -1, setting.AppSubURL) // Setting the lang cookie will trigger the middleware to reset the language ot previous state.
ctx.Redirect(setting.AppSubURL + "/")
}
diff --git a/routers/user/setting.go b/routers/user/setting.go
index 2d8b53ff6..f4326bf0f 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -12,6 +12,7 @@ import (
"strings"
"github.com/Unknwon/com"
+ "github.com/Unknwon/i18n"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
@@ -105,6 +106,7 @@ func SettingsPost(ctx *context.Context, form auth.UpdateProfileForm) {
ctx.User.KeepEmailPrivate = form.KeepEmailPrivate
ctx.User.Website = form.Website
ctx.User.Location = form.Location
+ ctx.User.Language = form.Language
if err := models.UpdateUserSetting(ctx.User); err != nil {
if _, ok := err.(models.ErrEmailAlreadyUsed); ok {
ctx.Flash.Error(ctx.Tr("form.email_been_used"))
@@ -115,8 +117,11 @@ func SettingsPost(ctx *context.Context, form auth.UpdateProfileForm) {
return
}
+ // Update the language to the one we just set
+ ctx.SetCookie("lang", ctx.User.Language, nil, setting.AppSubURL)
+
log.Trace("User settings updated: %s", ctx.User.Name)
- ctx.Flash.Success(ctx.Tr("settings.update_profile_success"))
+ ctx.Flash.Success(i18n.Tr(ctx.User.Language, "settings.update_profile_success"))
ctx.Redirect(setting.AppSubURL + "/user/settings")
}
diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl
index 091c2e2c5..4e6930e0f 100644
--- a/templates/user/settings/profile.tmpl
+++ b/templates/user/settings/profile.tmpl
@@ -40,6 +40,20 @@
+