%[2]s
nach %[3]s
zusammenführen
pulls.merged_title_desc=hat %[1]d Commits von %[2]s
nach %[3]s
%[4]s zusammengeführt
@@ -751,10 +774,18 @@ pulls.tab_files=Geänderte Dateien
pulls.reopen_to_merge=Bitte diesen Pull-Request wieder öffnen, um die Merge-Operation auszuführen.
pulls.merged=Zusammengeführt
pulls.has_merged=Der Pull-Request wurde zusammengeführt.
+pulls.data_broken=Dieser Pull-Requests ist kaputt, da Fork-Informationen gelöscht wurden.
+pulls.is_checking=Die Konfliktprüfung läuft noch. Bitte aktualisiere die Seite in wenigen Augenblicken.
pulls.can_auto_merge_desc=Dieser Pull-Request kann automatisch zusammengeführt werden.
+pulls.cannot_auto_merge_desc=Dieser Pull-Request kann nicht automatisch zusammengeführt werden, da es Konflikte gibt.
+pulls.cannot_auto_merge_helper=Bitte manuell zusammenführen, um die Konflikte zu lösen.
+pulls.no_merge_desc=Dieser Pull-Request kann nicht gemerged werden, da keine Mergeoptionen aktiviert sind.
+pulls.no_merge_helper=Aktiviere Mergeoptionen in den Repositoryeinstellungen oder merge den Pull-Request manuell.
pulls.merge_pull_request=Pull-Request zusammenführen
pulls.rebase_merge_pull_request=Rebase und Mergen
pulls.squash_merge_pull_request=Zusammenfassen und Mergen
+pulls.invalid_merge_option=Du kannst diese Mergeoption auf diesen Pull-Request nicht anwenden.
+pulls.open_unmerged_pull_exists=`Du kannst diesen Pull-Request nicht erneut öffnen, da noch ein anderer (#%d) mit identischen Eigenschaften offen ist.`
milestones.new=Neuer Meilenstein
milestones.open_tab=%d offen
@@ -763,6 +794,7 @@ milestones.closed=Geschlossen %s
milestones.no_due_date=Kein Fälligkeitsdatum
milestones.open=Öffnen
milestones.close=Schließen
+milestones.new_subheader=Benutze Meilensteine, um Issues zu organisieren und den Fortschritt darzustellen.
milestones.create=Meilenstein erstellen
milestones.title=Titel
milestones.desc=Beschreibung
@@ -771,6 +803,7 @@ milestones.clear=Feld leeren
milestones.invalid_due_date_format=Das Fälligkeitsdatum muss das Format 'JJJJ-MM-TT' haben.
milestones.create_success=Der Meilenstein '%s' wurde erstellt.
milestones.edit=Meilenstein bearbeiten
+milestones.edit_subheader=Benutze Meilensteine, um Issues zu organisieren und den Fortschritt darzustellen.
milestones.cancel=Abbrechen
milestones.modify=Meilenstein bearbeiten
milestones.edit_success=Die Änderungen am Meilenstein "%s" wurden gespeichert.
@@ -789,6 +822,7 @@ ext_wiki.desc=Verweis auf externes Wiki.
wiki=Wiki
wiki.welcome=Willkommen im Wiki.
+wiki.welcome_desc=Im Wiki kannst Dokumentation schreiben und mit Mitarbeitern teilen.
wiki.desc=Schreibe und teile Dokumentation mit Mitarbeitern.
wiki.create_first_page=Erstelle die erste Seite
wiki.page=Seite
@@ -800,6 +834,7 @@ wiki.last_commit_info=%s hat diese Seite bearbeitet %s
wiki.edit_page_button=Bearbeiten
wiki.new_page_button=Neue Seite
wiki.delete_page_button=Seite löschen
+wiki.delete_page_notice_1=Das Löschen der Wiki-Seite '%s' kann nicht Rückgängig gemacht werden. Fortfahren?
wiki.page_already_exists=Eine Wiki-Seite mit dem gleichen Namen existiert bereits.
wiki.reserved_page=Der Wiki-Seitenname "%s" ist reserviert.
wiki.pages=Seiten
@@ -838,6 +873,9 @@ activity.closed_issue_label=Geschlossen
activity.new_issues_count_1=Neuer Issue
activity.new_issues_count_n=Neue Issues
activity.new_issue_label=Geöffnet
+activity.title.unresolved_conv_1=%d offene Konversation
+activity.title.unresolved_conv_n=%d offene Konversationen
+activity.unresolved_conv_desc=Diese kürzlich geänderten Issues und Pull-Requests wurden noch nicht gelöst.
activity.unresolved_conv_label=Offen
activity.title.releases_1=%d Release
activity.title.releases_n=%d Releases
@@ -861,6 +899,7 @@ settings.githooks=Git-Hooks
settings.basic_settings=Grundeinstellungen
settings.mirror_settings=Mirror Einstellungen
settings.sync_mirror=Jetzt Synchronisieren
+settings.mirror_sync_in_progress=Mirror-Synchronisierung wird zurzeit ausgeführt. Komm in ein paar Minuten zurück.
settings.site=Webseite
settings.update_settings=Einstellungen speichern
settings.advanced_settings=Erweiterte Einstellungen
@@ -869,16 +908,27 @@ settings.use_internal_wiki=Eingebautes Wiki verwenden
settings.use_external_wiki=Externes Wiki verwenden
settings.external_wiki_url=Externe Wiki URL
settings.external_wiki_url_error=Die externe Wiki-URL ist ungültig.
+settings.external_wiki_url_desc=Besucher werden auf die externe Wiki-URL weitergeleitet wenn sie auf das Wiki-Tab klicken.
settings.issues_desc=Repository Issue-Tracker aktivieren
settings.use_internal_issue_tracker=Integrierten Issue-Tracker verwenden
settings.use_external_issue_tracker=Externen Issue-Tracker verwenden
settings.external_tracker_url=URL eines externen Issue Trackers
settings.external_tracker_url_error=Die URL des externen Issue-Trackers ist ungültig.
+settings.external_tracker_url_desc=Besucher werden auf die externe Issue-Tracker-URL weitergeleitet wenn sie auf das Issues-Tab klicken.
settings.tracker_url_format=URL-Format des externen Issue-Systems
+settings.tracker_issue_style=Namenskonvention des externen Issue-Trackers
settings.tracker_issue_style.numeric=Numerisch
settings.tracker_issue_style.alphanumeric=Alphanumerisch
+settings.tracker_url_format_desc=Du kannst die Platzhalter {user}
, {repo}
, {index}
für den Benutzernamen, den Namen des Repositories und die Issue-Nummer verwenden.
settings.enable_timetracker=Zeiterfassung aktivieren
+settings.allow_only_contributors_to_track_time=Nur Mitarbeitern erlauben, die Zeiterfassung zu nutzen
+settings.pulls_desc=Repository-Pull-Requests aktivieren
+settings.pulls.ignore_whitespace=Bei Konflikten Leerzeichen ignorieren
+settings.pulls.allow_merge_commits=Mergecommits aktivieren
+settings.pulls.allow_rebase_merge=Mergen von Commits durch Rebasen aktivieren
+settings.pulls.allow_squash_commits=Mergen von Commits durch Squash aktivieren
settings.admin_settings=Administratoreinstellungen
+settings.admin_enable_health_check=Repository-Health-Checks aktivieren (git fsck)
settings.danger_zone=Gefahrenzone
settings.new_owner_has_same_repo=Der neue Eigentümer hat bereits ein Repository mit dem gleichen Namen. Bitte wähle einen anderen Namen.
settings.convert=In ein normales Repository umwandeln
@@ -899,6 +949,8 @@ settings.wiki_deletion_success=Repository Wiki-Daten wurden gelöscht.
settings.delete=Dieses Repository löschen
settings.delete_desc=Wenn dieses Repository gelöscht wurde, gibt es keinen Weg zurück. Bitte sei vorsichtig.
settings.delete_notices_1=- Diese Operation kann NICHT rückgängig gemacht werden.
+settings.delete_notices_2=- Die Operation wird das %s-Repository dauerhaft löschen, inklusive der Dateien, Issues, Kommentare und Zugriffseinstellungen.
+settings.delete_notices_fork_1=- Nach dem Löschen werden alle Forks unabhängig.
settings.deletion_success=Das Repository wurde gelöscht.
settings.update_settings_success=Repository Einstellungen wurden aktualisiert.
settings.transfer_owner=Neuer Besitzer
@@ -909,30 +961,40 @@ settings.add_collaborator=Mitarbeiter hinzufügen
settings.add_collaborator_success=Der Mitarbeiter wurde hinzugefügt.
settings.delete_collaborator=Entfernen
settings.collaborator_deletion=Mitarbeiter entfernen
+settings.collaborator_deletion_desc=Nach dem Löschen wird dieser Mitarbeiter keinen Zugriff mehr auf dieses Repository haben. Fortfahren?
settings.remove_collaborator_success=Der Mitarbeiter wurde entfernt.
settings.search_user_placeholder=Benutzer suchen…
settings.org_not_allowed_to_be_collaborator=Organisationen können nicht als Mitarbeiter hinzugefügt werden.
settings.user_is_org_member=Der Benutzer ist ein Organisationsmitglied und kann nicht als Mitarbeiter hinzugefügt werden.
settings.add_webhook=Webhook hinzufügen
+settings.hooks_desc=Webhooks senden bei bestimmten Gitea-Events automatisch HTTP POST-Requets an einen Server. Lies mehr in unserer Anleitung zu Webhooks (Englisch).
settings.webhook_deletion=Webhook löschen
+settings.webhook_deletion_desc=Das Entfernen eines Webhooks löscht seine Einstellungen und Zustellungsverlauf. Fortfahren?
settings.webhook_deletion_success=Webhook wurde entfernt.
settings.webhook.test_delivery=Senden testen
+settings.webhook.test_delivery_desc=Teste diesen Webhook mit einem Fake-Event.
+settings.webhook.test_delivery_success=Ein Fake-Event wurde zur Auslieferungswarteschlange hinzugefügt. Es kann einige Sekunden dauern, bevor es im Zustellungsverlauf erscheint.
settings.webhook.request=Anfrage
settings.webhook.response=Antwort
settings.webhook.headers=Kopfzeilen
settings.webhook.payload=Inhalt
settings.webhook.body=Inhalt
+settings.githooks_desc=Git-Hooks werden von Git selbst bereitgestellt. Du kannst die Dateien der unterstützten Hooks in der Liste unten bearbeiten, um eigene Operationen einzubinden.
settings.githook_edit_desc=Wenn ein Hook nicht aktiv ist, wird der Standardinhalt benutzt. Lasse den Inhalt leer, um den Hook zu deaktivieren.
settings.githook_name=Hook-Name
settings.githook_content=Hook-Inhalt
settings.update_githook=Hook aktualisieren
+settings.add_webhook_desc=Gitea sendet einen POST
-Request mit festgelegtem Content-Type an die Ziel-URL. Mehr Informationen findest du in der Anleitung zu Webhooks (Englisch).
settings.payload_url=Ziel-URL
+settings.content_type=POST-Content-Type
settings.secret=Secret
settings.slack_username=Benutzername
settings.slack_icon_url=Icon-URL
settings.discord_username=Benutzername
settings.discord_icon_url=Icon-URL
settings.slack_color=Farbe
+settings.event_desc=Auslösen bei:
+settings.event_push_only=Push-Events
settings.event_send_everything=Alle Events
settings.event_choose=Benutzerdefinierte Events…
settings.event_create=Erstellen
@@ -943,20 +1005,34 @@ settings.event_push=Push
settings.event_push_desc=Git push in ein Repository.
settings.event_repository=Repository
settings.event_repository_desc=Repository erstellt oder gelöscht.
+settings.active=Event-Details mitversenden
+settings.active_helper=Informationen über das auslösende Event mitversenden.
settings.add_hook_success=Webhook wurde hinzugefügt.
settings.update_webhook=Webhook aktualisieren
settings.update_hook_success=Webhook wurde aktualisiert.
settings.delete_webhook=Webhook entfernen
settings.recent_deliveries=Letzte Zustellungen
settings.hook_type=Hook Typ
+settings.add_slack_hook_desc=Slack-Integration zu deinem Repository hinzufügen.
settings.slack_token=Token
settings.slack_domain=Domain
settings.slack_channel=Kanal
+settings.add_discord_hook_desc=Discord-Integration zu deinem Repository hinzufügen.
+settings.add_dingtalk_hook_desc=Dingtalk-Integration zu deinem Repository hinzufügen.
settings.deploy_keys=Deploy-Schlüssel
settings.add_deploy_key=Deploy-Schlüssel hinzufügen
+settings.deploy_key_desc=Deploy-Keys haben nur Lesezugriff auf das Repository.
settings.is_writable=Erlaube Schreibzugriff
+settings.is_writable_info=Erlaube diesem Deploy-Key auf das Repository zu pushen.
+settings.no_deploy_keys=Noch keine Deploy-Keys vorhanden.
settings.title=Titel
settings.deploy_key_content=Inhalt
+settings.key_been_used=Ein Deploy-Key mit identischem Inhalt wird bereits verwendet.
+settings.key_name_used=Ein Deploy-Key mit diesem Namen existiert bereits.
+settings.add_key_success=Der Deploy-Key '%s' wurde erfolgreich hinzugefügt.
+settings.deploy_key_deletion=Deploy-Key löschen
+settings.deploy_key_deletion_desc=Nach dem Löschen wird dieser Deploy-Key keinen Zugriff mehr auf dieses Repository haben. Fortfahren?
+settings.deploy_key_deletion_success=Der Deploy-Key wurde entfernt.
settings.branches=Branches
settings.protected_branch=Branch-Protection
settings.protected_branch_can_push=Push erlauben?
@@ -964,11 +1040,24 @@ settings.protected_branch_can_push_yes=Du kannst pushen
settings.protected_branch_can_push_no=Du kannst nicht pushen
settings.branch_protection=Branch-Schutz" für Branch '%s'
settings.protect_this_branch=Brach-Schutz aktivieren
+settings.protect_this_branch_desc=Verhindere Löschen und deaktiviere Git force push auf diese Branch.
+settings.protect_whitelist_committers=Push-Whitelist aktivieren
+settings.protect_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist Push-Beschränkungen zu umgehen.
+settings.protect_whitelist_users=Nutzer, die pushen dürfen:
settings.protect_whitelist_search_users=Benutzer suchen…
+settings.protect_whitelist_teams=Teams, die pushen dürfen:
settings.protect_whitelist_search_teams=Suche nach Teams…
+settings.protect_merge_whitelist_committers=Merge-Whitelist aktivieren
+settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist Pull-Requests in diese Branch zu mergen.
+settings.protect_merge_whitelist_users=Nutzer, die mergen dürfen:
+settings.protect_merge_whitelist_teams=Teams, die mergen dürfen:
settings.add_protected_branch=Schutz aktivieren
settings.delete_protected_branch=Schutz deaktivieren
+settings.update_protect_branch_success=Branch-protection für die Branch '%s' wurde geändert.
+settings.remove_protected_branch_success=Branch-protection für die Branch '%s' wurde deaktiviert.
settings.protected_branch_deletion=Brach-Schutz deaktivieren
+settings.protected_branch_deletion_desc=Wenn du die Branch-Protection deaktivierst, können alle Nutzer mit Schreibrechten auf die Branch pushen. Fortfahren?
+settings.default_branch_desc=Wähle eine Standardbranch für Pull-Requests und Code-Commits:
settings.choose_branch=Wähle eine Branch…
settings.no_protected_branch=Es gibt keine geschützten Branches.
@@ -985,6 +1074,7 @@ diff.view_file=Datei anzeigen
diff.file_suppressed=Datei-Diff unterdrückt, da er zu groß ist
diff.too_many_files=Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.
+releases.desc=Behalte den Überblick über Versionen und Downloads.
release.releases=Releases
release.new_release=Neues Release
release.draft=Entwurf
@@ -993,8 +1083,11 @@ release.stable=Stabil
release.edit=bearbeiten
release.ahead=%d Commits zu %s seit diesem Release
release.source_code=Quelltext
+release.new_subheader=In Releases werden Projektversionen verwaltet.
+release.edit_subheader=In Releases werden Projektversionen verwaltet.
release.tag_name=Tag-Name
release.target=Ziel
+release.tag_helper=Wähle einen existierenden oder erstelle einen neuen Tag.
release.title=Titel
release.content=Inhalt
release.write=Schreiben
@@ -1008,6 +1101,7 @@ release.save_draft=Entwurf speichern
release.edit_release=Release aktualisieren
release.delete_release=Release löschen
release.deletion=Release löschen
+release.deletion_desc=Wenn du ein Release löschst, wird das den dazugehörigen Git-Tag aus dem Repository löschen. Repository-Inhalte und History bleiben unverändert. Fortfahren?
release.deletion_success=Das Release wurde gelöscht.
release.tag_name_already_exist=Ein Release mit diesem Tag existiert bereits.
release.tag_name_invalid=Der Tag-Name ist ungültig.
@@ -1019,12 +1113,16 @@ branch.already_exists=Eine Branch mit dem Namen '%s' existiert bereits.
branch.delete_head=Löschen
branch.delete=Branch '%s' löschen
branch.delete_html=Branch löschen
+branch.delete_desc=Das Löschen einer Branch ist permanent. Es KANN NICHT Rückgängig gemacht werden. Fortfahren?
branch.deletion_success=Branch '%s' wurde gelöscht.
branch.deletion_failed=Branch '%s' konnte nicht gelöscht werden.
+branch.delete_branch_has_new_commits=Die Branch '%s' kann nicht gelöscht weden, da seit dem letzten Merge neue Commits hinzugefügt wurden.
branch.create_branch=Erstelle Branch %s
branch.create_from=von '%s'
branch.create_success=Branch '%s' wurde erstellt.
branch.branch_already_exists=Branch '%s' existiert bereits in diesem Repository.
+branch.branch_name_conflict=Der Branch-Name '%s' steht in Konflikt mit der bestehendem Branch '%s'.
+branch.tag_collision=Branch '%s' kann nicht erstellt werden, da in diesem Repository bereits ein Tag mit dem selben Namen existiert.
branch.deleted_by=Von %s gelöscht
branch.restore_success=Branch '%s' wurde wiederhergestellt.
branch.restore_failed=Wiederherstellung der Branch '%s' fehlgeschlagen.
@@ -1049,10 +1147,12 @@ org_desc=Beschreibung
team_name=Teamname
team_desc=Beschreibung
team_name_helper=Teamnamen sollten kurz und einprägsam sein.
+team_desc_helper=Beschreibe den Zweck oder die Rolle des Teams.
team_permission_desc=Berechtigungen
team_unit_desc=Zugriff auf Repositorybereiche erlauben
form.name_reserved=Der Organisationsname '%s' ist reserviert.
+form.name_pattern_not_allowed=Das Muster '%s' ist in Organisationsnamen nicht erlaubt.
form.create_org_not_allowed=Du bist nicht berechtigt eine Organisation zu erstellen.
settings=Einstellungen
@@ -1062,9 +1162,11 @@ settings.website=Webseite
settings.location=Standort
settings.update_settings=Einstellungen speichern
settings.update_setting_success=Organisationseinstellungen wurden aktualisiert.
+settings.change_orgname_prompt=Hinweis: Die Änderung des Organisationsnamens ändert auch ihre URL.
settings.update_avatar_success=Der Organisationsavatar wurde aktualisiert.
settings.delete=Organisation löschen
settings.delete_account=Diese Organisation löschen
+settings.delete_prompt=Die Organisation wird dauerhaft gelöscht. Dies KANN NICHT rückgängig gemacht werden!
settings.confirm_delete_account=Löschen
settings.delete_org_title=Organisation löschen
settings.delete_org_desc=Diese Organisation wird dauerhaft gelöscht. Fortfahren?
@@ -1072,6 +1174,8 @@ settings.hooks_desc=Webhooks hinzufügen, die für alle Reposit
members.membership_visibility=Sichtbarkeit der Mitgliedschaft:
members.public=Sichtbar
+members.public_helper=verstecken
+members.private=Versteckt
members.private_helper=sichtbar machen
members.member_role=Mitgliedsrolle:
members.owner=Besitzer
@@ -1086,16 +1190,22 @@ teams.leave=Verlassen
teams.read_access=Lesezugriff
teams.read_access_helper=Mitglieder können Teamrepositories ansehen und klonen.
teams.write_access=Schreibzugriff
+teams.write_access_helper=Mitglieder können Teamrepositories ansehen und auf sie pushen.
teams.admin_access=Administratorzugang
teams.admin_access_helper=Mitglieder können auf Team Repositories "pushen", von ihnen "pullen" und Mitarbeiter hinzufügen.
teams.no_desc=Dieses Team hat keine Beschreibung
teams.settings=Einstellungen
+teams.owners_permission_desc=Besitzer haben vollen Zugriff auf alle Repositories und Admin-Rechte für diese Organisation.
teams.members=Teammitglieder
teams.update_settings=Einstellungen aktualisieren
teams.delete_team=Team löschen
teams.add_team_member=Teammitglied hinzufügen
teams.delete_team_title=Team löschen
+teams.delete_team_desc=Das Löschen eines Teams wiederruft den Repository-Zugriff für seine Mitglieder. Fortfahren?
teams.delete_team_success=Das Team wurde gelöscht.
+teams.read_permission_desc=Dieses Team hat Lesezugriff: Mitglieder können Team-Repositories einsehen und klonen.
+teams.write_permission_desc=Dieses Team hat Schreibzugriff: Mitglieder können Team-Repositories einsehen und darauf pushen.
+teams.admin_permission_desc=Dieses Team hat Adminzugriff: Mitglieder dieses Teams können Team-Repositories ansehen, auf sie pushen und Mitarbeiter hinzufügen.
teams.repositories=Team-Repositories
teams.search_repo_placeholder=Repository durchsuchen…
teams.add_team_repository=Team-Repository hinzufügen
@@ -1116,7 +1226,9 @@ last_page=Letzte
total=Gesamt: %d
dashboard.statistic=Übersicht
+dashboard.operations=Wartungsoperationen
dashboard.system_status=System-Status
+dashboard.statistic_info=Gitea's Datenbank hat %d Benutzer, %d Organisationen, %d öffentliche Schlüssel, %d Repositories, %d Beobachtungen, %d Favoriten, %d Aktionen, %d Zugriffe, %d Issues, %d Kommentare, %d Konten sozialer Netzwerke, %d Gefolgte, %d Mirrors, %d Releases, %d Login-Quellen, %d Webhooks, %d Meilensteine, %d Label, %d Hook-Tasks, %d Teams, %d Aktualisierungs-Tasks, %d Anhänge.
dashboard.operation_name=Name der Operation
dashboard.operation_switch=Wechseln
dashboard.operation_run=Ausführen
@@ -1130,11 +1242,16 @@ dashboard.delete_missing_repos=Alle Repository-Datensätze mit verlorenen gegang
dashboard.delete_missing_repos_success=Alle Repository-Datensätze mit verlorenen Git-Dateien wurden gelöscht.
dashboard.git_gc_repos=Garbage Collection auf Repositories ausführen
dashboard.git_gc_repos_success=Alle Repositories haben Garbage Collection beendet.
+dashboard.resync_all_sshkeys='.ssh/authorized_keys'-Datei mit Gitea SSH-Keys neu schreiben. (Wenn Du den eingebauten SSH Server nutzt, musst du das nicht ausführen.)
+dashboard.resync_all_sshkeys_success=Alle von Gitea verwalteten öffentlichen Schlüssel wurden neu geschrieben.
+dashboard.resync_all_hooks=Synchronisiere pre-receive, update und post-receive Hooks für alle Repositories.
+dashboard.resync_all_hooks_success=Alle pre-receive, update und post-receive Repository-Hooks wurden synchronisiert.
dashboard.reinit_missing_repos=Alle Git-Repositories mit Einträgen neu einlesen
dashboard.reinit_missing_repos_success=Alle verlorenen Git-Repositories mit existierenden Einträgen wurden erfolgreich aktualisiert.
dashboard.sync_external_users=Externe Benutzerdaten synchronisieren
dashboard.sync_external_users_started=Externe Benutzersynchronisation gestartet.
dashboard.git_fsck=Healthchecks auf alle Repositories ausführen
+dashboard.git_fsck_started=Repository-Healthchecks gestartet.
dashboard.server_uptime=Server-Uptime
dashboard.current_goroutine=Aktuelle Goroutinen
dashboard.current_memory_usage=Aktuelle Speichernutzung
@@ -1173,21 +1290,28 @@ users.admin=Administrator
users.repos=Repositories
users.created=Registriert am
users.last_login=Letzte Anmeldung
+users.never_login=Hat sich noch nie eingeloggt
+users.send_register_notify=Benutzer-Registrierungsbenachrichtigung senden
users.new_success=Der Account '%s' wurde erstellt.
users.edit=Bearbeiten
users.auth_source=Authentifizierungsquelle
users.local=Lokal
+users.auth_login_name=Anmeldename zur Authentifizierung
+users.password_helper=Passwort leerlassen, um es nicht zu verändern.
users.update_profile_success=Der Account '%s' wurde aktualisiert.
users.edit_account=Benutzerkonto bearbeiten
users.max_repo_creation=Maximale Anzahl Repositories
users.max_repo_creation_desc=(Gib -1 ein, um das globale Standardlimit zu verwenden.)
users.is_activated=Account ist aktiviert
+users.prohibit_login=Anmelden deaktivieren
users.is_admin=Ist Administrator
users.allow_git_hook=Darf "Git Hooks" erstellen
users.allow_import_local=Darf lokale Repositories importieren
users.allow_create_organization=Darf Organisationen erstellen
users.update_profile=Benutzerkonto aktualisieren
users.delete_account=Benutzerkonto löschen
+users.still_own_repo=Dieser Benutzer besitzt noch mindestens ein Repository. Bitte lösche oder übertrage diese zuerst.
+users.still_has_org=Dieser Nutzer ist Mitglied einer Organisation. Du musst ihn zuerst aus allen Organisationen entfernen.
users.deletion_success=Der Account wurde gelöscht.
orgs.org_manage_panel=Organisationsverwaltung
@@ -1220,12 +1344,17 @@ 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 mit nur Lesezugriff.
auths.user_base=Basis für Benutzersuche
auths.user_dn=Benutzer DN
auths.attribute_username=Benutzername Attribut
+auths.attribute_username_placeholder=Leerlassen, um den in Gitea eingegebenen Benutzernamen zu verwenden.
auths.attribute_name=Vornamensattribut
auths.attribute_surname=Nachnamensattribut
auths.attribute_mail=E-Mail Attribut
+auths.attributes_in_bind=Hole Attribute im Bind-Kontext
+auths.use_paged_search=Seitensuche verwenden
+auths.search_page_size=Seitengröße
auths.filter=Benutzerfilter
auths.admin_filter=Admin Filter
auths.ms_ad_sa=MS AD Suchattribute
@@ -1233,6 +1362,7 @@ auths.smtp_auth=SMTP-Authentifizierungstyp
auths.smtphost=SMTP-Host
auths.smtpport=SMTP-Port
auths.allowed_domains=Erlaubte Domains
+auths.allowed_domains_helper=Leerlassen, um alle Domains zuzulassen. Trenne mehrere Domänen mit einem Komma (',').
auths.enable_tls=TLS-Verschlüsselung aktivieren
auths.skip_tls_verify=TLS Verifikation überspringen
auths.pam_service_name=PAM Dienstname
@@ -1240,6 +1370,7 @@ auths.oauth2_provider=OAuth2 Anbieter
auths.oauth2_clientID=Client-ID (Schlüssel)
auths.oauth2_clientSecret=Client-Secret
auths.openIdConnectAutoDiscoveryURL=OpenID Connect Auto Discovery URL
+auths.oauth2_use_custom_url=Benutzerdefinierte URLs anstelle von Standard-URLs verwenden
auths.oauth2_tokenURL=Token-URL
auths.oauth2_authURL=Authorisierungs-URL
auths.oauth2_profileURL=Profil-URL
@@ -1249,11 +1380,14 @@ auths.tips=Tipps
auths.tips.oauth2.general=OAuth2 Authentifizierung
auths.tips.oauth2.general.tip=Beim Registrieren einer neuen OAuth2 Authentifizierung sollte die Callback/Weiterleitungs-URL %[2]s
до %[3]s
+pulls.merged_title_desc=злито %[1]d комітів з %[2]s
до %[3]s
%[4]s
pulls.tab_conversation=Обговорення
pulls.tab_commits=Коміти
pulls.tab_files=Змінені файли
@@ -682,6 +691,7 @@ settings.external_tracker_url=URL зовнішньої системи відст
settings.tracker_url_format=Формат URL зовнішнього трекера задач
settings.tracker_issue_style.numeric=Цифровий
settings.tracker_issue_style.alphanumeric=Буквено-цифровий
+settings.enable_timetracker=Увімкнути відстеження часу
settings.admin_settings=Налаштування адміністратора
settings.danger_zone=Небезпечна зона
settings.new_owner_has_same_repo=Новий власник вже має репозиторій з такою назвою. Будь ласка, виберіть інше ім'я.
@@ -721,6 +731,7 @@ settings.event_pull_request=Запити до злиття
settings.event_push=Push
settings.event_repository=Репозиторій
settings.event_repository_desc=Репозиторій створений або видалено.
+settings.active=Додавати інформацію про події
settings.update_webhook=Оновити веб-хук
settings.hook_type=Тип хука
settings.slack_token=Токен
@@ -833,6 +844,7 @@ teams.settings=Налаштування
teams.members=Учасники команди
teams.update_settings=Оновити налаштування
teams.add_team_member=Додати учасника команди
+teams.write_permission_desc=Ця команда надає доступ на запис: учасники можуть отримувати й виконувати push команди до репозитрію.
teams.add_team_repository=Додати репозиторій команди
teams.remove_repo=Видалити
@@ -994,6 +1006,7 @@ config.enable_captcha=Увімкнути CAPTCHA
config.active_code_lives=Час актуальності кода підтвердження
config.default_keep_email_private=Приховати адресу електронної пошти за замовчуванням
config.default_allow_create_organization=Дозволити створення організацій за замовчуванням
+config.enable_timetracking=Увімкнути відстеження часу
config.default_enable_timetracking=Увімкнути відстеження часу за замовчуванням
config.webhook_config=Конфігурація web-хуків
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index c7e94726f4..e82892f08b 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -117,6 +117,7 @@ federated_avatar_lookup=启用 Federated 头像
federated_avatar_lookup_popup=启用 Federated Avatars 查找以使用开源的 Libravatar 服务。
disable_registration=禁止用户自助注册
disable_registration_popup=禁用用户自助注册。只有管理员才能创建新的用户帐户。
+allow_only_external_registration_popup=仅允许通过外部服务注册。
openid_signin=启用 OpenID 登录
openid_signin_popup=启用通过 OpenID 登录
openid_signup=启用 OpenID 自助注册
@@ -1442,6 +1443,7 @@ config.db_path_helper=(用于 "sqlite3" 和 "tidb")
config.service_config=服务配置
config.register_email_confirm=需要电子邮件确认注册
config.disable_register=禁止用户注册
+config.allow_only_external_registration=仅允许通过外部服务注册
config.enable_openid_signup=启用 OpenID 自注册
config.enable_openid_signin=启用 OpenID 登录
config.show_registration_button=显示注册按钮
diff --git a/routers/routes/routes.go b/routers/routes/routes.go
index 4f91f60cdd..f51d62d4d4 100644
--- a/routers/routes/routes.go
+++ b/routers/routes/routes.go
@@ -37,6 +37,7 @@ import (
"github.com/go-macaron/session"
"github.com/go-macaron/toolbox"
"gopkg.in/macaron.v1"
+ "net/http"
)
// NewMacaron initializes Macaron instance.
@@ -217,35 +218,54 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/user/settings", func() {
m.Get("", user.Settings)
m.Post("", bindIgnErr(auth.UpdateProfileForm{}), user.SettingsPost)
- m.Combo("/avatar").Get(user.SettingsAvatar).
- Post(binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost)
+ m.Post("/avatar", binding.MultipartForm(auth.AvatarForm{}), user.SettingsAvatarPost)
m.Post("/avatar/delete", user.SettingsDeleteAvatar)
- m.Combo("/email").Get(user.SettingsEmails).
- Post(bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
- m.Post("/email/delete", user.DeleteEmail)
- m.Get("/security", user.SettingsSecurity)
- m.Post("/security", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsSecurityPost)
- m.Group("/openid", func() {
- m.Combo("").Get(user.SettingsOpenID).
- Post(bindIgnErr(auth.AddOpenIDForm{}), user.SettingsOpenIDPost)
- m.Post("/delete", user.DeleteOpenID)
- m.Post("/toggle_visibility", user.ToggleOpenIDVisibility)
- }, openIDSignInEnabled)
- m.Combo("/keys").Get(user.SettingsKeys).
- Post(bindIgnErr(auth.AddKeyForm{}), user.SettingsKeysPost)
- m.Post("/keys/delete", user.DeleteKey)
+ m.Group("/account", func() {
+ m.Combo("").Get(user.SettingsAccount).Post(bindIgnErr(auth.ChangePasswordForm{}), user.SettingsAccountPost)
+ m.Post("/email", bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
+ m.Post("/email/delete", user.DeleteEmail)
+ m.Post("/delete", user.SettingsDelete)
+ })
+ m.Group("/security", func() {
+ m.Get("", user.SettingsSecurity)
+ m.Group("/two_factor", func() {
+ m.Post("/regenerate_scratch", user.SettingsTwoFactorRegenerateScratch)
+ m.Post("/disable", user.SettingsTwoFactorDisable)
+ m.Get("/enroll", user.SettingsTwoFactorEnroll)
+ m.Post("/enroll", bindIgnErr(auth.TwoFactorAuthForm{}), user.SettingsTwoFactorEnrollPost)
+ })
+ m.Group("/openid", func() {
+ m.Post("", bindIgnErr(auth.AddOpenIDForm{}), user.SettingsOpenIDPost)
+ m.Post("/delete", user.DeleteOpenID)
+ m.Post("/toggle_visibility", user.ToggleOpenIDVisibility)
+ }, openIDSignInEnabled)
+ m.Post("/account_link", user.SettingsDeleteAccountLink)
+ })
m.Combo("/applications").Get(user.SettingsApplications).
Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
m.Post("/applications/delete", user.SettingsDeleteApplication)
- m.Route("/delete", "GET,POST", user.SettingsDelete)
- m.Combo("/account_link").Get(user.SettingsAccountLinks).Post(user.SettingsDeleteAccountLink)
+ m.Combo("/keys").Get(user.SettingsKeys).
+ Post(bindIgnErr(auth.AddKeyForm{}), user.SettingsKeysPost)
+ m.Post("/keys/delete", user.DeleteKey)
m.Get("/organization", user.SettingsOrganization)
m.Get("/repos", user.SettingsRepos)
- m.Group("/security/two_factor", func() {
- m.Post("/regenerate_scratch", user.SettingsTwoFactorRegenerateScratch)
- m.Post("/disable", user.SettingsTwoFactorDisable)
- m.Get("/enroll", user.SettingsTwoFactorEnroll)
- m.Post("/enroll", bindIgnErr(auth.TwoFactorAuthForm{}), user.SettingsTwoFactorEnrollPost)
+
+ // redirects from old settings urls to new ones
+ // TODO: can be removed on next major version
+ m.Get("/avatar", func(ctx *context.Context) {
+ ctx.Redirect(setting.AppSubURL+"/user/settings", http.StatusMovedPermanently)
+ })
+ m.Get("/email", func(ctx *context.Context) {
+ ctx.Redirect(setting.AppSubURL+"/user/settings/account", http.StatusMovedPermanently)
+ })
+ m.Get("/delete", func(ctx *context.Context) {
+ ctx.Redirect(setting.AppSubURL+"/user/settings/account", http.StatusMovedPermanently)
+ })
+ m.Get("/openid", func(ctx *context.Context) {
+ ctx.Redirect(setting.AppSubURL+"/user/settings/security", http.StatusMovedPermanently)
+ })
+ m.Get("/account_link", func(ctx *context.Context) {
+ ctx.Redirect(setting.AppSubURL+"/user/settings/security", http.StatusMovedPermanently)
})
}, reqSignIn, func(ctx *context.Context) {
ctx.Data["PageIsUserSettings"] = true
diff --git a/routers/user/setting.go b/routers/user/setting.go
index f4326bf0f5..1c760e210c 100644
--- a/routers/user/setting.go
+++ b/routers/user/setting.go
@@ -30,18 +30,13 @@ import (
const (
tplSettingsProfile base.TplName = "user/settings/profile"
- tplSettingsAvatar base.TplName = "user/settings/avatar"
- tplSettingsEmails base.TplName = "user/settings/email"
- tplSettingsKeys base.TplName = "user/settings/keys"
- tplSettingsSocial base.TplName = "user/settings/social"
- tplSettingsApplications base.TplName = "user/settings/applications"
- tplSettingsTwofa base.TplName = "user/settings/twofa"
+ tplSettingsAccount base.TplName = "user/settings/account"
+ tplSettingsSecurity base.TplName = "user/settings/security"
tplSettingsTwofaEnroll base.TplName = "user/settings/twofa_enroll"
- tplSettingsAccountLink base.TplName = "user/settings/account_link"
+ tplSettingsApplications base.TplName = "user/settings/applications"
+ tplSettingsKeys base.TplName = "user/settings/keys"
tplSettingsOrganization base.TplName = "user/settings/organization"
tplSettingsRepositories base.TplName = "user/settings/repos"
- tplSettingsDelete base.TplName = "user/settings/delete"
- tplSettingsSecurity base.TplName = "user/settings/security"
)
// Settings render user's profile page
@@ -168,13 +163,6 @@ func UpdateAvatarSetting(ctx *context.Context, form auth.AvatarForm, ctxUser *mo
return nil
}
-// SettingsAvatar render user avatar page
-func SettingsAvatar(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsAvatar"] = true
- ctx.HTML(200, tplSettingsAvatar)
-}
-
// SettingsAvatarPost response for change user's avatar request
func SettingsAvatarPost(ctx *context.Context, form auth.AvatarForm) {
if err := UpdateAvatarSetting(ctx, form, ctx.User); err != nil {
@@ -183,7 +171,7 @@ func SettingsAvatarPost(ctx *context.Context, form auth.AvatarForm) {
ctx.Flash.Success(ctx.Tr("settings.update_avatar_success"))
}
- ctx.Redirect(setting.AppSubURL + "/user/settings/avatar")
+ ctx.Redirect(setting.AppSubURL + "/user/settings")
}
// SettingsDeleteAvatar render delete avatar page
@@ -192,38 +180,32 @@ func SettingsDeleteAvatar(ctx *context.Context) {
ctx.Flash.Error(err.Error())
}
- ctx.Redirect(setting.AppSubURL + "/user/settings/avatar")
+ ctx.Redirect(setting.AppSubURL + "/user/settings")
}
-// SettingsSecurity render change user's password page and 2FA
-func SettingsSecurity(ctx *context.Context) {
+// SettingsAccount renders change user's password, user's email and user suicide page
+func SettingsAccount(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsSecurity"] = true
+ ctx.Data["PageIsSettingsAccount"] = true
ctx.Data["Email"] = ctx.User.Email
- enrolled := true
- _, err := models.GetTwoFactorByUID(ctx.User.ID)
+ emails, err := models.GetEmailAddresses(ctx.User.ID)
if err != nil {
- if models.IsErrTwoFactorNotEnrolled(err) {
- enrolled = false
- } else {
- ctx.ServerError("SettingsTwoFactor", err)
- return
- }
+ ctx.ServerError("GetEmailAddresses", err)
+ return
}
+ ctx.Data["Emails"] = emails
- ctx.Data["TwofaEnrolled"] = enrolled
- ctx.HTML(200, tplSettingsSecurity)
+ ctx.HTML(200, tplSettingsAccount)
}
-// SettingsSecurityPost response for change user's password
-func SettingsSecurityPost(ctx *context.Context, form auth.ChangePasswordForm) {
+// SettingsAccountPost response for change user's password
+func SettingsAccountPost(ctx *context.Context, form auth.ChangePasswordForm) {
ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsSecurity"] = true
- ctx.Data["PageIsSettingsDelete"] = true
+ ctx.Data["PageIsSettingsAccount"] = true
if ctx.HasError() {
- ctx.HTML(200, tplSettingsSecurity)
+ ctx.HTML(200, tplSettingsAccount)
return
}
@@ -248,28 +230,13 @@ func SettingsSecurityPost(ctx *context.Context, form auth.ChangePasswordForm) {
ctx.Flash.Success(ctx.Tr("settings.change_password_success"))
}
- ctx.Redirect(setting.AppSubURL + "/user/settings/security")
-}
-
-// SettingsEmails render user's emails page
-func SettingsEmails(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsEmails"] = true
-
- emails, err := models.GetEmailAddresses(ctx.User.ID)
- if err != nil {
- ctx.ServerError("GetEmailAddresses", err)
- return
- }
- ctx.Data["Emails"] = emails
-
- ctx.HTML(200, tplSettingsEmails)
+ ctx.Redirect(setting.AppSubURL + "/user/settings/account")
}
// SettingsEmailPost response for change user's email
func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) {
ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsEmails"] = true
+ ctx.Data["PageIsSettingsAccount"] = true
// Make emailaddress primary.
if ctx.Query("_method") == "PRIMARY" {
@@ -279,7 +246,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) {
}
log.Trace("Email made primary: %s", ctx.User.Name)
- ctx.Redirect(setting.AppSubURL + "/user/settings/email")
+ ctx.Redirect(setting.AppSubURL + "/user/settings/account")
return
}
@@ -292,7 +259,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) {
ctx.Data["Emails"] = emails
if ctx.HasError() {
- ctx.HTML(200, tplSettingsEmails)
+ ctx.HTML(200, tplSettingsAccount)
return
}
@@ -303,7 +270,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) {
}
if err := models.AddEmailAddress(email); err != nil {
if models.IsErrEmailAlreadyUsed(err) {
- ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsEmails, &form)
+ ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form)
return
}
ctx.ServerError("AddEmailAddress", err)
@@ -323,7 +290,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) {
}
log.Trace("Email address added: %s", email.Email)
- ctx.Redirect(setting.AppSubURL + "/user/settings/email")
+ ctx.Redirect(setting.AppSubURL + "/user/settings/account")
}
// DeleteEmail response for delete user's email
@@ -336,7 +303,164 @@ func DeleteEmail(ctx *context.Context) {
ctx.Flash.Success(ctx.Tr("settings.email_deletion_success"))
ctx.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/email",
+ "redirect": setting.AppSubURL + "/user/settings/account",
+ })
+}
+
+// SettingsDelete render user suicide page and response for delete user himself
+func SettingsDelete(ctx *context.Context) {
+ ctx.Data["Title"] = ctx.Tr("settings")
+ ctx.Data["PageIsSettingsAccount"] = true
+
+ if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
+ if models.IsErrUserNotExist(err) {
+ ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), tplSettingsAccount, nil)
+ } else {
+ ctx.ServerError("UserSignIn", err)
+ }
+ return
+ }
+
+ if err := models.DeleteUser(ctx.User); err != nil {
+ switch {
+ case models.IsErrUserOwnRepos(err):
+ ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
+ ctx.Redirect(setting.AppSubURL + "/user/settings/account")
+ case models.IsErrUserHasOrgs(err):
+ ctx.Flash.Error(ctx.Tr("form.still_has_org"))
+ ctx.Redirect(setting.AppSubURL + "/user/settings/account")
+ default:
+ ctx.ServerError("DeleteUser", err)
+ }
+ } else {
+ log.Trace("Account deleted: %s", ctx.User.Name)
+ ctx.Redirect(setting.AppSubURL + "/")
+ }
+}
+
+// SettingsSecurity render change user's password page and 2FA
+func SettingsSecurity(ctx *context.Context) {
+ ctx.Data["Title"] = ctx.Tr("settings")
+ ctx.Data["PageIsSettingsSecurity"] = true
+
+ enrolled := true
+ _, err := models.GetTwoFactorByUID(ctx.User.ID)
+ if err != nil {
+ if models.IsErrTwoFactorNotEnrolled(err) {
+ enrolled = false
+ } else {
+ ctx.ServerError("SettingsTwoFactor", err)
+ return
+ }
+ }
+ ctx.Data["TwofaEnrolled"] = enrolled
+
+ accountLinks, err := models.ListAccountLinks(ctx.User)
+ if err != nil {
+ ctx.ServerError("ListAccountLinks", err)
+ return
+ }
+
+ // map the provider display name with the LoginSource
+ sources := make(map[*models.LoginSource]string)
+ for _, externalAccount := range accountLinks {
+ if loginSource, err := models.GetLoginSourceByID(externalAccount.LoginSourceID); err == nil {
+ var providerDisplayName string
+ if loginSource.IsOAuth2() {
+ providerTechnicalName := loginSource.OAuth2().Provider
+ providerDisplayName = models.OAuth2Providers[providerTechnicalName].DisplayName
+ } else {
+ providerDisplayName = loginSource.Name
+ }
+ sources[loginSource] = providerDisplayName
+ }
+ }
+ ctx.Data["AccountLinks"] = sources
+
+ if ctx.Query("openid.return_to") != "" {
+ settingsOpenIDVerify(ctx)
+ return
+ }
+
+ openid, err := models.GetUserOpenIDs(ctx.User.ID)
+ if err != nil {
+ ctx.ServerError("GetUserOpenIDs", err)
+ return
+ }
+ ctx.Data["OpenIDs"] = openid
+
+ ctx.HTML(200, tplSettingsSecurity)
+}
+
+// SettingsDeleteAccountLink delete a single account link
+func SettingsDeleteAccountLink(ctx *context.Context) {
+ if _, err := models.RemoveAccountLink(ctx.User, ctx.QueryInt64("loginSourceID")); err != nil {
+ ctx.Flash.Error("RemoveAccountLink: " + err.Error())
+ } else {
+ ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success"))
+ }
+
+ ctx.JSON(200, map[string]interface{}{
+ "redirect": setting.AppSubURL + "/user/settings/security",
+ })
+}
+
+// SettingsApplications render manage access token page
+func SettingsApplications(ctx *context.Context) {
+ ctx.Data["Title"] = ctx.Tr("settings")
+ ctx.Data["PageIsSettingsApplications"] = true
+
+ tokens, err := models.ListAccessTokens(ctx.User.ID)
+ if err != nil {
+ ctx.ServerError("ListAccessTokens", err)
+ return
+ }
+ ctx.Data["Tokens"] = tokens
+
+ ctx.HTML(200, tplSettingsApplications)
+}
+
+// SettingsApplicationsPost response for add user's access token
+func SettingsApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm) {
+ ctx.Data["Title"] = ctx.Tr("settings")
+ ctx.Data["PageIsSettingsApplications"] = true
+
+ if ctx.HasError() {
+ tokens, err := models.ListAccessTokens(ctx.User.ID)
+ if err != nil {
+ ctx.ServerError("ListAccessTokens", err)
+ return
+ }
+ ctx.Data["Tokens"] = tokens
+ ctx.HTML(200, tplSettingsApplications)
+ return
+ }
+
+ t := &models.AccessToken{
+ UID: ctx.User.ID,
+ Name: form.Name,
+ }
+ if err := models.NewAccessToken(t); err != nil {
+ ctx.ServerError("NewAccessToken", err)
+ return
+ }
+
+ ctx.Flash.Success(ctx.Tr("settings.generate_token_success"))
+ ctx.Flash.Info(t.Sha1)
+
+ ctx.Redirect(setting.AppSubURL + "/user/settings/applications")
+}
+
+// SettingsDeleteApplication response for delete user access token
+func SettingsDeleteApplication(ctx *context.Context) {
+ if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id"), ctx.User.ID); err != nil {
+ ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error())
+ } else {
+ ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
+ }
+
+ ctx.JSON(200, map[string]interface{}{
+ "redirect": setting.AppSubURL + "/user/settings/applications",
})
}
@@ -471,65 +595,6 @@ func DeleteKey(ctx *context.Context) {
})
}
-// SettingsApplications render user's access tokens page
-func SettingsApplications(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsApplications"] = true
-
- tokens, err := models.ListAccessTokens(ctx.User.ID)
- if err != nil {
- ctx.ServerError("ListAccessTokens", err)
- return
- }
- ctx.Data["Tokens"] = tokens
-
- ctx.HTML(200, tplSettingsApplications)
-}
-
-// SettingsApplicationsPost response for add user's access token
-func SettingsApplicationsPost(ctx *context.Context, form auth.NewAccessTokenForm) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsApplications"] = true
-
- if ctx.HasError() {
- tokens, err := models.ListAccessTokens(ctx.User.ID)
- if err != nil {
- ctx.ServerError("ListAccessTokens", err)
- return
- }
- ctx.Data["Tokens"] = tokens
- ctx.HTML(200, tplSettingsApplications)
- return
- }
-
- t := &models.AccessToken{
- UID: ctx.User.ID,
- Name: form.Name,
- }
- if err := models.NewAccessToken(t); err != nil {
- ctx.ServerError("NewAccessToken", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("settings.generate_token_success"))
- ctx.Flash.Info(t.Sha1)
-
- ctx.Redirect(setting.AppSubURL + "/user/settings/applications")
-}
-
-// SettingsDeleteApplication response for delete user access token
-func SettingsDeleteApplication(ctx *context.Context) {
- if err := models.DeleteAccessTokenByID(ctx.QueryInt64("id"), ctx.User.ID); err != nil {
- ctx.Flash.Error("DeleteAccessTokenByID: " + err.Error())
- } else {
- ctx.Flash.Success(ctx.Tr("settings.delete_token_success"))
- }
-
- ctx.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/applications",
- })
-}
-
// SettingsTwoFactorRegenerateScratch regenerates the user's 2FA scratch code.
func SettingsTwoFactorRegenerateScratch(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
@@ -695,86 +760,6 @@ func SettingsTwoFactorEnrollPost(ctx *context.Context, form auth.TwoFactorAuthFo
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
}
-// SettingsAccountLinks render the account links settings page
-func SettingsAccountLinks(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsAccountLink"] = true
-
- accountLinks, err := models.ListAccountLinks(ctx.User)
- if err != nil {
- ctx.ServerError("ListAccountLinks", err)
- return
- }
-
- // map the provider display name with the LoginSource
- sources := make(map[*models.LoginSource]string)
- for _, externalAccount := range accountLinks {
- if loginSource, err := models.GetLoginSourceByID(externalAccount.LoginSourceID); err == nil {
- var providerDisplayName string
- if loginSource.IsOAuth2() {
- providerTechnicalName := loginSource.OAuth2().Provider
- providerDisplayName = models.OAuth2Providers[providerTechnicalName].DisplayName
- } else {
- providerDisplayName = loginSource.Name
- }
- sources[loginSource] = providerDisplayName
- }
- }
- ctx.Data["AccountLinks"] = sources
-
- ctx.HTML(200, tplSettingsAccountLink)
-}
-
-// SettingsDeleteAccountLink delete a single account link
-func SettingsDeleteAccountLink(ctx *context.Context) {
- if _, err := models.RemoveAccountLink(ctx.User, ctx.QueryInt64("loginSourceID")); err != nil {
- ctx.Flash.Error("RemoveAccountLink: " + err.Error())
- } else {
- ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success"))
- }
-
- ctx.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/account_link",
- })
-}
-
-// SettingsDelete render user suicide page and response for delete user himself
-func SettingsDelete(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsDelete"] = true
- ctx.Data["Email"] = ctx.User.Email
-
- if ctx.Req.Method == "POST" {
- if _, err := models.UserSignIn(ctx.User.Name, ctx.Query("password")); err != nil {
- if models.IsErrUserNotExist(err) {
- ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_password"), tplSettingsDelete, nil)
- } else {
- ctx.ServerError("UserSignIn", err)
- }
- return
- }
-
- if err := models.DeleteUser(ctx.User); err != nil {
- switch {
- case models.IsErrUserOwnRepos(err):
- ctx.Flash.Error(ctx.Tr("form.still_own_repo"))
- ctx.Redirect(setting.AppSubURL + "/user/settings/delete")
- case models.IsErrUserHasOrgs(err):
- ctx.Flash.Error(ctx.Tr("form.still_has_org"))
- ctx.Redirect(setting.AppSubURL + "/user/settings/delete")
- default:
- ctx.ServerError("DeleteUser", err)
- }
- } else {
- log.Trace("Account deleted: %s", ctx.User.Name)
- ctx.Redirect(setting.AppSubURL + "/")
- }
- return
- }
-
- ctx.HTML(200, tplSettingsDelete)
-}
-
// SettingsOrganization render all the organization of the user
func SettingsOrganization(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
diff --git a/routers/user/setting_openid.go b/routers/user/setting_openid.go
index 92eb636e29..7716466120 100644
--- a/routers/user/setting_openid.go
+++ b/routers/user/setting_openid.go
@@ -8,40 +8,15 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/auth/openid"
- "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
-const (
- tplSettingsOpenID base.TplName = "user/settings/openid"
-)
-
-// SettingsOpenID renders change user's openid page
-func SettingsOpenID(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsOpenID"] = true
-
- if ctx.Query("openid.return_to") != "" {
- settingsOpenIDVerify(ctx)
- return
- }
-
- openid, err := models.GetUserOpenIDs(ctx.User.ID)
- if err != nil {
- ctx.ServerError("GetUserOpenIDs", err)
- return
- }
- ctx.Data["OpenIDs"] = openid
-
- ctx.HTML(200, tplSettingsOpenID)
-}
-
// SettingsOpenIDPost response for change user's openid
func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) {
ctx.Data["Title"] = ctx.Tr("settings")
- ctx.Data["PageIsSettingsOpenID"] = true
+ ctx.Data["PageIsSettingsSecurity"] = true
if ctx.HasError() {
openid, err := models.GetUserOpenIDs(ctx.User.ID)
@@ -50,7 +25,7 @@ func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) {
return
}
ctx.Data["OpenIDs"] = openid
- ctx.HTML(200, tplSettingsOpenID)
+ ctx.HTML(200, tplSettingsSecurity)
return
}
@@ -62,7 +37,7 @@ func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) {
id, err := openid.Normalize(form.Openid)
if err != nil {
- ctx.RenderWithErr(err.Error(), tplSettingsOpenID, &form)
+ ctx.RenderWithErr(err.Error(), tplSettingsSecurity, &form)
return
}
form.Openid = id
@@ -78,15 +53,15 @@ func SettingsOpenIDPost(ctx *context.Context, form auth.AddOpenIDForm) {
// Check that the OpenID is not already used
for _, obj := range oids {
if obj.URI == id {
- ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsOpenID, &form)
+ ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsSecurity, &form)
return
}
}
- redirectTo := setting.AppURL + "user/settings/openid"
+ redirectTo := setting.AppURL + "user/settings/security"
url, err := openid.RedirectURL(id, redirectTo, setting.AppURL)
if err != nil {
- ctx.RenderWithErr(err.Error(), tplSettingsOpenID, &form)
+ ctx.RenderWithErr(err.Error(), tplSettingsSecurity, &form)
return
}
ctx.Redirect(url)
@@ -107,7 +82,7 @@ func settingsOpenIDVerify(ctx *context.Context) {
id, err := openid.Verify(fullURL)
if err != nil {
- ctx.RenderWithErr(err.Error(), tplSettingsOpenID, &auth.AddOpenIDForm{
+ ctx.RenderWithErr(err.Error(), tplSettingsSecurity, &auth.AddOpenIDForm{
Openid: id,
})
return
@@ -118,7 +93,7 @@ func settingsOpenIDVerify(ctx *context.Context) {
oid := &models.UserOpenID{UID: ctx.User.ID, URI: id}
if err = models.AddUserOpenID(oid); err != nil {
if models.IsErrOpenIDAlreadyUsed(err) {
- ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsOpenID, &auth.AddOpenIDForm{Openid: id})
+ ctx.RenderWithErr(ctx.Tr("form.openid_been_used", id), tplSettingsSecurity, &auth.AddOpenIDForm{Openid: id})
return
}
ctx.ServerError("AddUserOpenID", err)
@@ -127,7 +102,7 @@ func settingsOpenIDVerify(ctx *context.Context) {
log.Trace("Associated OpenID %s to user %s", id, ctx.User.Name)
ctx.Flash.Success(ctx.Tr("settings.add_openid_success"))
- ctx.Redirect(setting.AppSubURL + "/user/settings/openid")
+ ctx.Redirect(setting.AppSubURL + "/user/settings/security")
}
// DeleteOpenID response for delete user's openid
@@ -140,7 +115,7 @@ func DeleteOpenID(ctx *context.Context) {
ctx.Flash.Success(ctx.Tr("settings.openid_deletion_success"))
ctx.JSON(200, map[string]interface{}{
- "redirect": setting.AppSubURL + "/user/settings/openid",
+ "redirect": setting.AppSubURL + "/user/settings/security",
})
}
@@ -151,5 +126,5 @@ func ToggleOpenIDVisibility(ctx *context.Context) {
return
}
- ctx.Redirect(setting.AppSubURL + "/user/settings/openid")
+ ctx.Redirect(setting.AppSubURL + "/user/settings/security")
}
diff --git a/routers/user/setting_test.go b/routers/user/setting_test.go
index 72b1b83143..6aa9a07439 100644
--- a/routers/user/setting_test.go
+++ b/routers/user/setting_test.go
@@ -56,7 +56,7 @@ func TestChangePassword(t *testing.T) {
test.LoadUser(t, ctx, 2)
test.LoadRepo(t, ctx, 1)
- SettingsSecurityPost(ctx, auth.ChangePasswordForm{
+ SettingsAccountPost(ctx, auth.ChangePasswordForm{
OldPassword: req.OldPassword,
Password: req.NewPassword,
Retype: req.Retype,
diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl
index 669ee3264b..837f8bd949 100644
--- a/templates/user/profile.tmpl
+++ b/templates/user/profile.tmpl
@@ -5,7 +5,7 @@
{{.i18n.Tr "settings.email_deletion_desc"}}
+{{.i18n.Tr "settings.delete_account_desc"}}
+{{.i18n.Tr "settings.remove_account_link_desc"}}
-{{.i18n.Tr "settings.new_token_desc"}}
{{.i18n.Tr "settings.delete_account_desc"}}
-{{.i18n.Tr "settings.email_deletion_desc"}}
-{{.i18n.Tr "settings.openid_deletion_desc"}}
-{{.i18n.Tr "settings.twofa_desc"}}
- {{if .TwofaEnrolled}} -{{$.i18n.Tr "settings.twofa_is_enrolled" | Str2html }}
- - - {{else}} -{{.i18n.Tr "settings.twofa_not_enrolled"}}
- - {{end}} -{{.i18n.Tr "settings.twofa_disable_desc"}}
-{{.i18n.Tr "settings.remove_account_link_desc"}}
+{{.i18n.Tr "settings.openid_deletion_desc"}}
+{{.i18n.Tr "settings.twofa_desc"}}
+ {{if .TwofaEnrolled}} +{{$.i18n.Tr "settings.twofa_is_enrolled" | Str2html }}
+ + + {{else}} +{{.i18n.Tr "settings.twofa_not_enrolled"}}
+ + {{end}} +{{.i18n.Tr "settings.twofa_disable_desc"}}
+{{.i18n.Tr "settings.twofa_desc"}}
- {{if .TwofaEnrolled}} -{{$.i18n.Tr "settings.twofa_is_enrolled" | Str2html }}
- - - {{else}} -{{.i18n.Tr "settings.twofa_not_enrolled"}}
- - {{end}} -{{.i18n.Tr "settings.twofa_disable_desc"}}
-