diff --git a/modules/ssh/init.go b/modules/ssh/init.go
index 432cda0c13..ebc17de69c 100644
--- a/modules/ssh/init.go
+++ b/modules/ssh/init.go
@@ -85,7 +85,9 @@ func Init(ctx context.Context) error {
detailConcat := strings.Join(unexpectedKeys, "\n\t")
log.Fatal("An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either:\n"+
"Option 1: Delete the file %s, and Forgejo will recreate it with only expected ssh public keys.\n"+
- "Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file.\n\t"+
+ "Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file.\n"+
+ "Option 3: If unused, disable SSH support by setting [server].DISABLE_SSH=true in Forgejo's config file.\n"+
+ "\t"+
detailConcat, filepath.Join(setting.SSH.RootPath, "authorized_keys"))
}
}
diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json
index 51920dda8f..90133f36ff 100644
--- a/options/locale_next/locale_en-US.json
+++ b/options/locale_next/locale_en-US.json
@@ -1,252 +1,254 @@
{
"home.welcome.no_activity": "No activity",
- "home.welcome.activity_hint": "There is nothing in your feed yet. Your actions and activity from repositories that you watch will show up here.",
- "home.explore_repos": "Explore repositories",
- "home.explore_users": "Explore users",
- "home.explore_orgs": "Explore organizations",
- "fork.n_forks": {
- "one": "%s fork",
- "other": "%s forks"
- },
- "stars.list.none": "No one starred this repo.",
- "stars.n_stars": {
- "one": "%s star",
- "other": "%s stars"
- },
- "watch.list.none": "No one is watching this repo.",
- "watch.n_watchers": {
- "one": "%s watcher",
- "other": "%s watchers"
- },
- "followers.incoming.list.self.none": "No one is following your profile.",
- "followers.incoming.list.none": "No one is following this user.",
- "followers.outgoing.list.self.none": "You are not following anyone.",
- "followers.outgoing.list.none": "%s isn't following anyone.",
- "relativetime.now": "now",
- "relativetime.future": "in future",
- "relativetime.mins": {
- "one": "%d minute ago",
- "other": "%d minutes ago"
- },
- "relativetime.hours": {
- "one": "%d hour ago",
- "other": "%d hours ago"
- },
- "relativetime.days": {
- "one": "%d day ago",
- "other": "%d days ago"
- },
- "relativetime.weeks": {
- "one": "%d week ago",
- "other": "%d weeks ago"
- },
- "relativetime.months": {
- "one": "%d month ago",
- "other": "%d months ago"
- },
- "relativetime.years": {
- "one": "%d year ago",
- "other": "%d years ago"
- },
- "relativetime.1day": "yesterday",
- "relativetime.2days": "two days ago",
- "relativetime.1week": "last week",
- "relativetime.2weeks": "two weeks ago",
- "relativetime.1month": "last month",
- "relativetime.2months": "two months ago",
- "relativetime.1year": "last year",
- "relativetime.2years": "two years ago",
- "repo.issues.filter_poster.hint": "Filter by the author",
- "repo.issues.filter_assignee.hint": "Filter by assigned user",
- "repo.issues.filter_reviewers.hint": "Filter by user who reviewed",
- "repo.issues.filter_mention.hint": "Filter by mentioned user",
- "repo.issues.filter_modified.hint": "Filter by last modified date",
- "repo.issues.filter_sort.hint": "Sort by: created/comments/updated/deadline",
- "issues.updated": "updated %s",
- "repo.pulls.poster_manage_approval": "Manage approval",
- "repo.pulls.poster_requires_approval": "Some workflows are waiting to be reviewed.",
- "repo.pulls.poster_requires_approval.tooltip": "The author of this pull request is not trusted to run workflows triggered by a pull request created from a forked repository or with AGit. The workflows triggered by a `pull_request` event will not run until they are approved.",
- "repo.pulls.poster_is_trusted": "The author of this pull request is always trusted to run workflows.",
- "repo.pulls.poster_is_trusted.tooltip": "The author of this pull request is explicitly trusted to run workflows triggered by `pull_request` events.",
- "repo.pulls.poster_trust_deny": "Deny",
- "repo.pulls.poster_trust_deny.tooltip": "The workflows waiting approval will be canceled.",
- "repo.pulls.poster_trust_once": "Approve once",
- "repo.pulls.poster_trust_once.tooltip": "The workflows triggered by a `pull_request` event will run on this commit but will need to be approved for all future commits pushed to this pull request.",
- "repo.pulls.poster_trust_always": "Approve always",
- "repo.pulls.poster_trust_always.tooltip": "The workflows triggered by a `pull_request` event will run on this commit and there will be no need to approve runs from this pull request or future pull requests authored by the same user.",
- "repo.pulls.poster_trust_revoke": "Revoke",
- "repo.pulls.poster_trust_revoke.tooltip": "The author of this pull request will no longer be trusted to run workflows triggered by a `pull_request` event, each run will have to be manually approved.",
- "repo.pulls.already_merged": "Merge failed: This pull request has already been merged.",
- "repo.pulls.merged_title_desc": {
- "one": "merged %[1]d commit from %[2]s into %[3]s %[4]s",
- "other": "merged %[1]d commits from %[2]s into %[3]s %[4]s"
- },
- "repo.pulls.title_desc": {
- "one": "wants to merge %[1]d commit from %[2]s into %[3]s",
- "other": "wants to merge %[1]d commits from %[2]s into %[3]s"
- },
- "repo.pulls.maintainers_can_edit": "Maintainers can edit this pull request.",
- "repo.pulls.maintainers_cannot_edit": "Maintainers cannot edit this pull request.",
- "repo.form.cannot_create": "All spaces in which you can create repositories have reached the limit of repositories.",
- "migrate.form.error.url_credentials": "The URL contains credentials, put them in the username and password fields respectively",
- "migrate.github.description": "Migrate data from github.com or GitHub Enterprise server.",
- "migrate.git.description": "Migrate a repository only from any Git service.",
- "migrate.gitea.description": "Migrate data from gitea.com or other Gitea instances.",
- "migrate.gitlab.description": "Migrate data from gitlab.com or other GitLab instances.",
- "migrate.gogs.description": "Migrate data from notabug.org or other Gogs instances.",
- "migrate.onedev.description": "Migrate data from code.onedev.io or other OneDev instances.",
- "migrate.gitbucket.description": "Migrate data from GitBucket instances.",
- "migrate.codebase.description": "Migrate data from codebasehq.com.",
- "migrate.forgejo.description": "Migrate data from codeberg.org or other Forgejo instances.",
- "repo.issue_indexer.title": "Issue Indexer",
- "search.milestone_kind": "Search milestones…",
- "search.syntax": "Search syntax",
- "search.fuzzy": "Fuzzy",
- "search.fuzzy_tooltip": "Include results is an approximate match to the search term",
- "repo.settings.push_mirror.branch_filter.label": "Branch filter (optional)",
- "repo.settings.push_mirror.branch_filter.description": "Branches to be mirrored. Leave blank to mirror all branches. See %[2]s documentation for syntax. Examples: main, release/*",
- "incorrect_root_url": "This Forgejo instance is configured to be served on \"%s\". You are currently viewing Forgejo through a different URL, which may cause parts of the application to break. The canonical URL is controlled by Forgejo admins via the ROOT_URL setting in the app.ini.",
- "themes.names.forgejo-auto": "Forgejo (follow system theme)",
- "themes.names.forgejo-light": "Forgejo light",
- "themes.names.forgejo-dark": "Forgejo dark",
- "error.not_found.title": "Page not found",
- "warning.repository.out_of_sync": "The database representation of this repository is out of synchronization. If this warning is still shown after pushing a commit to this repository contact the administrator.",
- "alert.asset_load_failed": "Failed to load asset files from {path}. Please make sure the asset files can be accessed.",
- "alert.range_error": " must be a number between %[1]s and %[2]s.",
- "install.invalid_lfs_path": "Unable to create the LFS root at the specified path: %[1]s",
- "profile.actions.tooltip": "More actions",
- "profile.edit.link": "Edit profile",
- "feed.atom.link": "Atom feed",
- "keys.ssh.link": "SSH keys",
- "keys.gpg.link": "GPG keys",
- "keys.verify.token.hint": "The token is only valid for 1 minute. Get a new one if it expired.",
- "admin.config.moderation_config": "Moderation configuration",
- "admin.moderation.moderation_reports": "Moderation reports",
- "admin.moderation.reports": "Reports",
- "admin.moderation.no_open_reports": "There are currently no open reports.",
- "admin.moderation.deleted_content_ref": "Reported content with type %[1]v and id %[2]d no longer exists",
- "moderation.report.mark_as_handled": "Mark as handled",
- "moderation.report.mark_as_ignored": "Mark as ignored",
- "moderation.action.account.delete": "Delete account",
- "moderation.action.account.suspend": "Suspend account",
- "moderation.action.repo.delete": "Delete repository",
- "moderation.action.issue.delete": "Delete issue",
- "moderation.action.comment.delete": "Delete comment",
- "moderation.unknown_action": "Unknown action",
- "moderation.users.cannot_suspend_self": "You cannot suspend yourself.",
- "moderation.users.cannot_suspend_admins": "Users with admin privileges cannot be suspended.",
- "moderation.users.cannot_suspend_org": "Organizations cannot be suspended.",
- "moderation.users.already_suspended": "User account is already suspended.",
- "moderation.users.suspend_success": "The user account has been suspended.",
- "moderation.users.cannot_delete_admins": "Users with admin privileges cannot be deleted.",
- "moderation.issue.deletion_success": "The issue has been deleted.",
- "moderation.comment.deletion_success": "The comment has been deleted.",
- "moderation.report_abuse": "Report abuse",
- "moderation.report_content": "Report content",
- "moderation.report_abuse_form.header": "Report abuse to administrator",
- "moderation.report_abuse_form.details": "This form should be used to report users who create spam profiles, repositories, issues, comments or behave inappropriately.",
- "moderation.report_abuse_form.invalid": "Invalid arguments",
- "moderation.report_abuse_form.already_reported": "You've already reported this content",
- "moderation.abuse_category": "Category",
- "moderation.abuse_category.placeholder": "Select a category",
- "moderation.abuse_category.spam": "Spam",
- "moderation.abuse_category.malware": "Malware",
- "moderation.abuse_category.illegal_content": "Illegal content",
- "moderation.abuse_category.other_violations": "Other violations of platform rules",
- "moderation.report_remarks": "Remarks",
- "moderation.report_remarks.placeholder": "Please provide some details regarding the abuse you are reporting.",
- "moderation.submit_report": "Submit report",
- "moderation.reporting_failed": "Unable to submit the new abuse report: %v",
- "moderation.reported_thank_you": "Thank you for your report. The administration has been made aware of it.",
- "mail.actions.successful_run_after_failure_subject": "Workflow %[1]s recovered in repository %[2]s",
- "mail.actions.not_successful_run_subject": "Workflow %[1]s failed in repository %[2]s",
- "mail.actions.successful_run_after_failure": "Workflow %[1]s recovered in repository %[2]s",
- "mail.actions.not_successful_run": "Workflow %[1]s failed in repository %[2]s",
- "mail.actions.run_info_cur_status": "This Run's Status: %[1]s (just updated from %[2]s)",
- "mail.actions.run_info_previous_status": "Previous Run's Status: %[1]s",
- "mail.actions.run_info_sha": "Commit: %[1]s",
- "mail.actions.run_info_trigger": "Triggered because: %[1]s by: %[2]s",
- "mail.issue.action.close_by_commit": "%[1]s closed %[2]s in commit %[3]s.",
- "repo.diff.commit.next-short": "Next",
- "repo.diff.commit.previous-short": "Prev",
- "discussion.locked": "This discussion has been locked. Commenting is limited to contributors.",
- "discussion.sidebar.reference": "Reference",
- "editor.textarea.tab_hint": "Line already indented. Press Tab again or Escape to leave the editor.",
- "editor.textarea.shift_tab_hint": "No indentation on this line. Press Shift + Tab again or Escape to leave the editor.",
- "admin.auths.allow_username_change": "Allow username change",
- "admin.auths.allow_username_change.description": "Allow users to change their username in the profile settings",
- "admin.dashboard.cleanup_offline_runners": "Cleanup offline runners",
- "admin.dashboard.remove_resolved_reports": "Remove resolved reports",
- "admin.dashboard.actions_action_user": "Revoke Forgejo Actions trust for inactive users",
- "admin.dashboard.transfer_lingering_logs": "Transfer actions logs of finished actions jobs from the database to storage",
- "admin.config.security": "Security configuration",
- "admin.config.global_2fa_requirement.title": "Global two-factor requirement",
- "admin.config.global_2fa_requirement.none": "No",
- "admin.config.global_2fa_requirement.all": "All users",
- "admin.config.global_2fa_requirement.admin": "Administrators",
- "settings.visibility.description": "Profile visibility affects others' ability to access your non-private repositories. Learn more.",
- "settings.twofa_unroll_unavailable": "Two-factor authentication is required for your account and cannot be disabled.",
- "settings.twofa_reenroll": "Re-enroll two-factor authentication",
- "settings.twofa_reenroll.description": "Re-enroll your two-factor authentication",
- "settings.must_enable_2fa": "This Forgejo instance requires users to enable two-factor authentication before they can access their accounts.",
- "error.must_enable_2fa": "This Forgejo instance requires users to enable two-factor authentication before they can access their accounts. Enable it at: %s",
- "avatar.constraints_hint": "Custom avatar may not exceed %[1]s in size or be larger than %[2]dx%[3]d pixels",
- "user.ghost.tooltip": "This user has been deleted, or cannot be matched.",
- "og.repo.summary_card.alt_description": "Summary card of repository %[1]s, described as: %[2]s",
- "repo.commit.load_tags_failed": "Load tags failed because of internal error",
- "compare.branches.title": "Compare branches",
- "migrate.pagure.description": "Migrate data from pagure.io or other Pagure instances.",
- "migrate.pagure.incorrect_url": "Incorrect source repository URL has been provided",
- "migrate.pagure.project_url": "Pagure project URL",
- "migrate.pagure.project_example": "The Pagure project URL, e.g. https://pagure.io/pagure",
- "migrate.pagure.token_label": "Pagure API Token",
- "migrate.pagure.private_issues.summary": "Private Issues (Optional)",
- "migrate.pagure.private_issues.description": "This feature is designed to create a second repository containing only private issues from your Pagure project for archive purposes. First, perform a normal migration (without a token) to import all public content. Then, if you have private issues to preserve, create a separate repository using this token option to archive those private issues.",
- "migrate.pagure.private_issues.warning": "Be sure to set the repository visibility above to Private if you are using the API key to import private issues. This prevents accidentally exposing private content in a public repository.",
- "migrate.pagure.token.placeholder": "Only for creating private issues archive",
- "release.n_downloads": {
- "one": "%s download",
- "other": "%s downloads"
- },
- "actions.status.diagnostics.waiting": {
- "one": "Waiting for a runner with the following label: %s",
- "other": "Waiting for a runner with the following labels: %s"
- },
- "actions.runs.run_attempt_label": "Run attempt #%[1]s (%[2]s)",
- "actions.runs.viewing_out_of_date_run": "You are viewing an out-of-date run of this job that was executed %[1]s.",
- "actions.runs.view_most_recent_run": "View most recent run",
- "actions.workflow.job_parsing_error": "Unable to parse jobs in workflow: %v",
- "actions.workflow.event_detection_error": "Unable to parse supported events in workflow: %v",
- "actions.workflow.persistent_incomplete_matrix": "Unable to evaluate `strategy.matrix` of job %[1]s due to a `needs` expression that was invalid. It may reference a job that is not in it's 'needs' list (%[2]s), or an output that doesn't exist on one of those jobs.",
- "actions.workflow.incomplete_matrix_missing_job": "Unable to evaluate `strategy.matrix` of job %[1]s: job %[2]s is not in the `needs` list of job %[1]s (%[3]s).",
+ "home.welcome.activity_hint": "There is nothing in your feed yet. Your actions and activity from repositories that you watch will show up here.",
+ "home.explore_repos": "Explore repositories",
+ "home.explore_users": "Explore users",
+ "home.explore_orgs": "Explore organizations",
+ "fork.n_forks": {
+ "one": "%s fork",
+ "other": "%s forks"
+ },
+ "stars.list.none": "No one starred this repo.",
+ "stars.n_stars": {
+ "one": "%s star",
+ "other": "%s stars"
+ },
+ "watch.list.none": "No one is watching this repo.",
+ "watch.n_watchers": {
+ "one": "%s watcher",
+ "other": "%s watchers"
+ },
+ "followers.incoming.list.self.none": "No one is following your profile.",
+ "followers.incoming.list.none": "No one is following this user.",
+ "followers.outgoing.list.self.none": "You are not following anyone.",
+ "followers.outgoing.list.none": "%s isn't following anyone.",
+ "relativetime.now": "now",
+ "relativetime.future": "in future",
+ "relativetime.mins": {
+ "one": "%d minute ago",
+ "other": "%d minutes ago"
+ },
+ "relativetime.hours": {
+ "one": "%d hour ago",
+ "other": "%d hours ago"
+ },
+ "relativetime.days": {
+ "one": "%d day ago",
+ "other": "%d days ago"
+ },
+ "relativetime.weeks": {
+ "one": "%d week ago",
+ "other": "%d weeks ago"
+ },
+ "relativetime.months": {
+ "one": "%d month ago",
+ "other": "%d months ago"
+ },
+ "relativetime.years": {
+ "one": "%d year ago",
+ "other": "%d years ago"
+ },
+ "relativetime.1day": "yesterday",
+ "relativetime.2days": "two days ago",
+ "relativetime.1week": "last week",
+ "relativetime.2weeks": "two weeks ago",
+ "relativetime.1month": "last month",
+ "relativetime.2months": "two months ago",
+ "relativetime.1year": "last year",
+ "relativetime.2years": "two years ago",
+ "repo.issues.filter_poster.hint": "Filter by the author",
+ "repo.issues.filter_assignee.hint": "Filter by assigned user",
+ "repo.issues.filter_reviewers.hint": "Filter by user who reviewed",
+ "repo.issues.filter_mention.hint": "Filter by mentioned user",
+ "repo.issues.filter_modified.hint": "Filter by last modified date",
+ "repo.issues.filter_sort.hint": "Sort by: created/comments/updated/deadline",
+ "issues.updated": "updated %s",
+ "repo.pulls.poster_manage_approval": "Manage approval",
+ "repo.pulls.poster_requires_approval": "Some workflows are waiting to be reviewed.",
+ "repo.pulls.poster_requires_approval.tooltip": "The author of this pull request is not trusted to run workflows triggered by a pull request created from a forked repository or with AGit. The workflows triggered by a `pull_request` event will not run until they are approved.",
+ "repo.pulls.poster_is_trusted": "The author of this pull request is always trusted to run workflows.",
+ "repo.pulls.poster_is_trusted.tooltip": "The author of this pull request is explicitly trusted to run workflows triggered by `pull_request` events.",
+ "repo.pulls.poster_trust_deny": "Deny",
+ "repo.pulls.poster_trust_deny.tooltip": "The workflows waiting approval will be canceled.",
+ "repo.pulls.poster_trust_once": "Approve once",
+ "repo.pulls.poster_trust_once.tooltip": "The workflows triggered by a `pull_request` event will run on this commit but will need to be approved for all future commits pushed to this pull request.",
+ "repo.pulls.poster_trust_always": "Approve always",
+ "repo.pulls.poster_trust_always.tooltip": "The workflows triggered by a `pull_request` event will run on this commit and there will be no need to approve runs from this pull request or future pull requests authored by the same user.",
+ "repo.pulls.poster_trust_revoke": "Revoke",
+ "repo.pulls.poster_trust_revoke.tooltip": "The author of this pull request will no longer be trusted to run workflows triggered by a `pull_request` event, each run will have to be manually approved.",
+ "repo.pulls.already_merged": "Merge failed: This pull request has already been merged.",
+ "repo.pulls.merged_title_desc": {
+ "one": "merged %[1]d commit from %[2]s into %[3]s %[4]s",
+ "other": "merged %[1]d commits from %[2]s into %[3]s %[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "wants to merge %[1]d commit from %[2]s into %[3]s",
+ "other": "wants to merge %[1]d commits from %[2]s into %[3]s"
+ },
+ "repo.pulls.maintainers_can_edit": "Maintainers can edit this pull request.",
+ "repo.pulls.maintainers_cannot_edit": "Maintainers cannot edit this pull request.",
+ "repo.form.cannot_create": "All spaces in which you can create repositories have reached the limit of repositories.",
+ "migrate.form.error.url_credentials": "The URL contains credentials, put them in the username and password fields respectively",
+ "migrate.github.description": "Migrate data from github.com or GitHub Enterprise server.",
+ "migrate.git.description": "Migrate a repository only from any Git service.",
+ "migrate.gitea.description": "Migrate data from gitea.com or other Gitea instances.",
+ "migrate.gitlab.description": "Migrate data from gitlab.com or other GitLab instances.",
+ "migrate.gogs.description": "Migrate data from notabug.org or other Gogs instances.",
+ "migrate.onedev.description": "Migrate data from code.onedev.io or other OneDev instances.",
+ "migrate.gitbucket.description": "Migrate data from GitBucket instances.",
+ "migrate.codebase.description": "Migrate data from codebasehq.com.",
+ "migrate.forgejo.description": "Migrate data from codeberg.org or other Forgejo instances.",
+ "repo.issue_indexer.title": "Issue Indexer",
+ "search.milestone_kind": "Search milestones…",
+ "search.syntax": "Search syntax",
+ "search.fuzzy": "Fuzzy",
+ "search.fuzzy_tooltip": "Include results is an approximate match to the search term",
+ "repo.settings.push_mirror.branch_filter.label": "Branch filter (optional)",
+ "repo.settings.push_mirror.branch_filter.description": "Branches to be mirrored. Leave blank to mirror all branches. See %[2]s documentation for syntax. Examples: main, release/*",
+ "incorrect_root_url": "This Forgejo instance is configured to be served on \"%s\". You are currently viewing Forgejo through a different URL, which may cause parts of the application to break. The canonical URL is controlled by Forgejo admins via the ROOT_URL setting in the app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (follow system theme)",
+ "themes.names.forgejo-light": "Forgejo light",
+ "themes.names.forgejo-dark": "Forgejo dark",
+ "error.not_found.title": "Page not found",
+ "warning.repository.out_of_sync": "The database representation of this repository is out of synchronization. If this warning is still shown after pushing a commit to this repository contact the administrator.",
+ "alert.asset_load_failed": "Failed to load asset files from {path}. Please make sure the asset files can be accessed.",
+ "alert.range_error": " must be a number between %[1]s and %[2]s.",
+ "install.invalid_lfs_path": "Unable to create the LFS root at the specified path: %[1]s",
+ "profile.actions.tooltip": "More actions",
+ "profile.edit.link": "Edit profile",
+ "feed.atom.link": "Atom feed",
+ "keys.ssh.link": "SSH keys",
+ "keys.gpg.link": "GPG keys",
+ "keys.verify.token.hint": "The token is only valid for 1 minute. Get a new one if it expired.",
+ "admin.config.moderation_config": "Moderation configuration",
+ "admin.moderation.moderation_reports": "Moderation reports",
+ "admin.moderation.reports": "Reports",
+ "admin.moderation.no_open_reports": "There are currently no open reports.",
+ "admin.moderation.deleted_content_ref": "Reported content with type %[1]v and id %[2]d no longer exists",
+ "moderation.report.mark_as_handled": "Mark as handled",
+ "moderation.report.mark_as_ignored": "Mark as ignored",
+ "moderation.action.account.delete": "Delete account",
+ "moderation.action.account.suspend": "Suspend account",
+ "moderation.action.repo.delete": "Delete repository",
+ "moderation.action.issue.delete": "Delete issue",
+ "moderation.action.comment.delete": "Delete comment",
+ "moderation.unknown_action": "Unknown action",
+ "moderation.users.cannot_suspend_self": "You cannot suspend yourself.",
+ "moderation.users.cannot_suspend_admins": "Users with admin privileges cannot be suspended.",
+ "moderation.users.cannot_suspend_org": "Organizations cannot be suspended.",
+ "moderation.users.already_suspended": "User account is already suspended.",
+ "moderation.users.suspend_success": "The user account has been suspended.",
+ "moderation.users.cannot_delete_admins": "Users with admin privileges cannot be deleted.",
+ "moderation.issue.deletion_success": "The issue has been deleted.",
+ "moderation.comment.deletion_success": "The comment has been deleted.",
+ "moderation.report_abuse": "Report abuse",
+ "moderation.report_content": "Report content",
+ "moderation.report_abuse_form.header": "Report abuse to administrator",
+ "moderation.report_abuse_form.details": "This form should be used to report users who create spam profiles, repositories, issues, comments or behave inappropriately.",
+ "moderation.report_abuse_form.invalid": "Invalid arguments",
+ "moderation.report_abuse_form.already_reported": "You've already reported this content",
+ "moderation.abuse_category": "Category",
+ "moderation.abuse_category.placeholder": "Select a category",
+ "moderation.abuse_category.spam": "Spam",
+ "moderation.abuse_category.malware": "Malware",
+ "moderation.abuse_category.illegal_content": "Illegal content",
+ "moderation.abuse_category.other_violations": "Other violations of platform rules",
+ "moderation.report_remarks": "Remarks",
+ "moderation.report_remarks.placeholder": "Please provide some details regarding the abuse you are reporting.",
+ "moderation.submit_report": "Submit report",
+ "moderation.reporting_failed": "Unable to submit the new abuse report: %v",
+ "moderation.reported_thank_you": "Thank you for your report. The administration has been made aware of it.",
+ "mail.actions.successful_run_after_failure_subject": "Workflow %[1]s recovered in repository %[2]s",
+ "mail.actions.not_successful_run_subject": "Workflow %[1]s failed in repository %[2]s",
+ "mail.actions.successful_run_after_failure": "Workflow %[1]s recovered in repository %[2]s",
+ "mail.actions.not_successful_run": "Workflow %[1]s failed in repository %[2]s",
+ "mail.actions.run_info_cur_status": "This Run's Status: %[1]s (just updated from %[2]s)",
+ "mail.actions.run_info_previous_status": "Previous Run's Status: %[1]s",
+ "mail.actions.run_info_sha": "Commit: %[1]s",
+ "mail.actions.run_info_trigger": "Triggered because: %[1]s by: %[2]s",
+ "mail.issue.action.close_by_commit": "%[1]s closed %[2]s in commit %[3]s.",
+ "repo.diff.commit.next-short": "Next",
+ "repo.diff.commit.previous-short": "Prev",
+ "discussion.locked": "This discussion has been locked. Commenting is limited to contributors.",
+ "discussion.sidebar.reference": "Reference",
+ "editor.textarea.tab_hint": "Line already indented. Press Tab again or Escape to leave the editor.",
+ "editor.textarea.shift_tab_hint": "No indentation on this line. Press Shift + Tab again or Escape to leave the editor.",
+ "admin.auths.allow_username_change": "Allow username change",
+ "admin.auths.allow_username_change.description": "Allow users to change their username in the profile settings",
+ "admin.dashboard.cleanup_offline_runners": "Cleanup offline runners",
+ "admin.dashboard.remove_resolved_reports": "Remove resolved reports",
+ "admin.dashboard.actions_action_user": "Revoke Forgejo Actions trust for inactive users",
+ "admin.dashboard.transfer_lingering_logs": "Transfer actions logs of finished actions jobs from the database to storage",
+ "admin.config.security": "Security configuration",
+ "admin.config.global_2fa_requirement.title": "Global two-factor requirement",
+ "admin.config.global_2fa_requirement.none": "No",
+ "admin.config.global_2fa_requirement.all": "All users",
+ "admin.config.global_2fa_requirement.admin": "Administrators",
+ "settings.visibility.description": "Profile visibility affects others' ability to access your non-private repositories. Learn more.",
+ "settings.twofa_unroll_unavailable": "Two-factor authentication is required for your account and cannot be disabled.",
+ "settings.twofa_reenroll": "Re-enroll two-factor authentication",
+ "settings.twofa_reenroll.description": "Re-enroll your two-factor authentication",
+ "settings.must_enable_2fa": "This Forgejo instance requires users to enable two-factor authentication before they can access their accounts.",
+ "error.must_enable_2fa": "This Forgejo instance requires users to enable two-factor authentication before they can access their accounts. Enable it at: %s",
+ "avatar.constraints_hint": "Custom avatar may not exceed %[1]s in size or be larger than %[2]dx%[3]d pixels",
+ "user.ghost.tooltip": "This user has been deleted, or cannot be matched.",
+ "og.repo.summary_card.alt_description": "Summary card of repository %[1]s, described as: %[2]s",
+ "repo.commit.load_tags_failed": "Load tags failed because of internal error",
+ "compare.branches.title": "Compare branches",
+ "migrate.pagure.description": "Migrate data from pagure.io or other Pagure instances.",
+ "migrate.pagure.incorrect_url": "Incorrect source repository URL has been provided",
+ "migrate.pagure.project_url": "Pagure project URL",
+ "migrate.pagure.project_example": "The Pagure project URL, e.g. https://pagure.io/pagure",
+ "migrate.pagure.token_label": "Pagure API Token",
+ "migrate.pagure.private_issues.summary": "Private Issues (Optional)",
+ "migrate.pagure.private_issues.description": "This feature is designed to create a second repository containing only private issues from your Pagure project for archive purposes. First, perform a normal migration (without a token) to import all public content. Then, if you have private issues to preserve, create a separate repository using this token option to archive those private issues.",
+ "migrate.pagure.private_issues.warning": "Be sure to set the repository visibility above to Private if you are using the API key to import private issues. This prevents accidentally exposing private content in a public repository.",
+ "migrate.pagure.token.placeholder": "Only for creating private issues archive",
+ "release.n_downloads": {
+ "one": "%s download",
+ "other": "%s downloads"
+ },
+ "actions.status.diagnostics.waiting": {
+ "one": "Waiting for a runner with the following label: %s",
+ "other": "Waiting for a runner with the following labels: %s"
+ },
+ "actions.runs.run_attempt_label": "Run attempt #%[1]s (%[2]s)",
+ "actions.runs.viewing_out_of_date_run": "You are viewing an out-of-date run of this job that was executed %[1]s.",
+ "actions.runs.view_most_recent_run": "View most recent run",
+ "actions.workflow.job_parsing_error": "Unable to parse jobs in workflow: %v",
+ "actions.workflow.event_detection_error": "Unable to parse supported events in workflow: %v",
+ "actions.workflow.persistent_incomplete_matrix": "Unable to evaluate `strategy.matrix` of job %[1]s due to a `needs` expression that was invalid. It may reference a job that is not in it's 'needs' list (%[2]s), or an output that doesn't exist on one of those jobs.",
+ "actions.workflow.incomplete_matrix_missing_job": "Unable to evaluate `strategy.matrix` of job %[1]s: job %[2]s is not in the `needs` list of job %[1]s (%[3]s).",
"actions.workflow.incomplete_matrix_missing_output": "Unable to evaluate `strategy.matrix` of job %[1]s: job %[2]s does not have an output %[3]s.",
- "actions.workflow.incomplete_matrix_unknown_cause": "Unable to evaluate `strategy.matrix` of job %[1]s: unknown error.",
- "actions.workflow.incomplete_runson_missing_job": "Unable to evaluate `runs-on` of job %[1]s: job %[2]s is not in the `needs` list of job %[1]s (%[3]s).",
+ "actions.workflow.incomplete_matrix_unknown_cause": "Unable to evaluate `strategy.matrix` of job %[1]s: unknown error.",
+ "actions.workflow.incomplete_runson_missing_job": "Unable to evaluate `runs-on` of job %[1]s: job %[2]s is not in the `needs` list of job %[1]s (%[3]s).",
"actions.workflow.incomplete_runson_missing_output": "Unable to evaluate `runs-on` of job %[1]s: job %[2]s does not have an output %[3]s.",
- "actions.workflow.incomplete_runson_missing_matrix_dimension": "Unable to evaluate `runs-on` of job %[1]s: matrix dimension %[2]s does not exist.",
- "actions.workflow.incomplete_runson_unknown_cause": "Unable to evaluate `runs-on` of job %[1]s: unknown error.",
- "actions.workflow.pre_execution_error": "Workflow was not executed due to an error that blocked the execution attempt.",
- "pulse.n_active_issues": {
- "one": "%s active issue",
- "other": "%s active issues"
- },
- "pulse.n_active_prs": {
- "one": "%s active pull request",
- "other": "%s active pull requests"
- },
- "teams.add_all_repos.modal.header": "Add all repositories",
- "teams.remove_all_repos.modal.header": "Remove all repositories",
- "admin.auths.oauth2_quota_group_claim_name": "Claim name providing group names for this source to be used for quota management. (Optional)",
- "admin.auths.oauth2_quota_group_map": "Map claimed groups to quota groups. (Optional - requires claim name above)",
- "admin.auths.oauth2_quota_group_map_removal": "Remove users from synchronized quota groups if user does not belong to corresponding group.",
- "editor.search": "Search",
- "editor.find_previous": "Previous find",
- "editor.find_next": "Next find",
- "editor.replace": "Replace",
- "editor.replace_all": "Replace all",
- "editor.toggle_case": "Toggle case sensitivity",
- "editor.toggle_regex": "Toggle using regular expressions",
- "editor.toggle_whole_word": "Toggle matching whole words",
- "repo.view.gitmodules_too_large": "The .gitmodules file is too large and will be ignored (on API calls for instance)",
- "meta.last_line": "Thank you for translating Forgejo! This line isn't seen by the users but it serves other purposes in the translation management. You can place a fun fact in the translation instead of translating it."
+ "actions.workflow.incomplete_runson_missing_matrix_dimension": "Unable to evaluate `runs-on` of job %[1]s: matrix dimension %[2]s does not exist.",
+ "actions.workflow.incomplete_runson_unknown_cause": "Unable to evaluate `runs-on` of job %[1]s: unknown error.",
+ "actions.workflow.pre_execution_error": "Workflow was not executed due to an error that blocked the execution attempt.",
+ "pulse.n_active_issues": {
+ "one": "%s active issue",
+ "other": "%s active issues"
+ },
+ "pulse.n_active_prs": {
+ "one": "%s active pull request",
+ "other": "%s active pull requests"
+ },
+ "teams.add_all_repos.modal.header": "Add all repositories",
+ "teams.remove_all_repos.modal.header": "Remove all repositories",
+ "admin.auths.oauth2_quota_group_claim_name": "Claim name providing group names for this source to be used for quota management. (Optional)",
+ "admin.auths.oauth2_quota_group_map": "Map claimed groups to quota groups. (Optional - requires claim name above)",
+ "admin.auths.oauth2_quota_group_map_removal": "Remove users from synchronized quota groups if user does not belong to corresponding group.",
+ "editor.search": "Search",
+ "editor.find_previous": "Previous find",
+ "editor.find_next": "Next find",
+ "editor.replace": "Replace",
+ "editor.replace_all": "Replace all",
+ "editor.toggle_case": "Toggle case sensitivity",
+ "editor.toggle_regex": "Toggle using regular expressions",
+ "editor.toggle_whole_word": "Toggle matching whole words",
+ "repo.view.gitmodules_too_large": "The .gitmodules file is too large and will be ignored (on API calls for instance)",
+ "install.ssh_authorized_keys_inspection_error": "Failed to inspect existing authorized_keys file: %v",
+ "install.ssh_authorized_keys_unexpected_key": "Enabling SSH for Forgejo conflicts with the file located at %s that contains existing SSH keys. Suggestions: use a dedicated system user for Forgejo, or disable SSH.",
+ "meta.last_line": "Thank you for translating Forgejo! This line isn't seen by the users but it serves other purposes in the translation management. You can place a fun fact in the translation instead of translating it."
}
diff --git a/routers/init.go b/routers/init.go
index 6313d9a3ad..4fd708c47b 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -9,7 +9,6 @@ import (
"runtime"
"forgejo.org/models"
- asymkey_model "forgejo.org/models/asymkey"
auth_model "forgejo.org/models/auth"
"forgejo.org/modules/cache"
"forgejo.org/modules/eventsource"
@@ -95,10 +94,6 @@ func syncAppConfForGit(ctx context.Context) error {
if updated {
log.Info("re-sync repository hooks ...")
mustInitCtx(ctx, repo_service.SyncRepositoryHooks)
-
- log.Info("re-write ssh public keys ...")
- mustInitCtx(ctx, asymkey_model.RewriteAllPublicKeys)
-
return system.AppState.Set(ctx, runtimeState)
}
return nil
diff --git a/routers/install/install.go b/routers/install/install.go
index 63a3f965f4..243f4a8f19 100644
--- a/routers/install/install.go
+++ b/routers/install/install.go
@@ -15,6 +15,7 @@ import (
"strings"
"time"
+ "forgejo.org/models/asymkey"
"forgejo.org/models/db"
db_install "forgejo.org/models/db/install"
"forgejo.org/models/gitea_migrations"
@@ -403,6 +404,25 @@ func SubmitInstall(ctx *context.Context) {
} else {
cfg.Section("server").Key("DISABLE_SSH").SetValue("false")
cfg.Section("server").Key("SSH_PORT").SetValue(fmt.Sprint(form.SSHPort))
+
+ sshKeyErrors, err := asymkey.InspectPublicKeys(ctx)
+ if err != nil {
+ ctx.RenderWithErr(ctx.Tr("install.ssh_authorized_keys_inspection_error", err), tplInstall, &form)
+ return
+ }
+
+ var authorizedKeysWillCauseFatalError bool
+ for _, finding := range sshKeyErrors {
+ if finding.Type == asymkey.InspectionResultUnexpectedKey {
+ // Any single finding of this type would cause `ssh.Init` to have a fatal error on Forgejo startup, so
+ // let's note it here while the install page is still usable and allow users to deal with it.
+ authorizedKeysWillCauseFatalError = true
+ }
+ }
+ if authorizedKeysWillCauseFatalError {
+ ctx.RenderWithErr(ctx.Tr("install.ssh_authorized_keys_unexpected_key", filepath.Join(setting.SSH.RootPath, "authorized_keys")), tplInstall, &form)
+ return
+ }
}
if form.LFSRootPath != "" {