aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKerwin Bryant <kerwin612@qq.com>2025-06-22 02:48:06 +0800
committerGitHub <noreply@github.com>2025-06-21 18:48:06 +0000
commit0548c10293ddac68444bad261a43024eef48643b (patch)
treeab48b23d9d69dc07ed19556768d9fe19f2a64be3
parent7de114a332c713eca9406da6c5a8eb02fe0c6f00 (diff)
downloadgitea-0548c10293ddac68444bad261a43024eef48643b.tar.gz
gitea-0548c10293ddac68444bad261a43024eef48643b.zip
Add post-installation redirect based on admin account status (#34493)
This PR adds a feature to direct users to appropriate pages after system installation: - If no admin credentials were provided during installation, redirect to the registration page with a prominent notice about creating the first administrative account - If admin credentials were already set, redirect directly to the login page ![4d396ad132d9b57fc4f45a62117177f1](https://github.com/user-attachments/assets/3a5d8700-9194-4d3b-a862-e64c8c347932) --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
-rw-r--r--models/user/user.go14
-rw-r--r--options/locale/locale_en-US.ini1
-rw-r--r--routers/install/install.go2
-rw-r--r--routers/web/auth/auth.go12
-rw-r--r--templates/post-install.tmpl2
-rw-r--r--templates/user/auth/signup_inner.tmpl3
-rw-r--r--web_src/js/features/install.ts2
7 files changed, 32 insertions, 4 deletions
diff --git a/models/user/user.go b/models/user/user.go
index 86a3549345..7c871bf575 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -831,6 +831,20 @@ type CountUserFilter struct {
IsActive optional.Option[bool]
}
+// HasUsers checks whether there are any users in the database, or only one user exists.
+func HasUsers(ctx context.Context) (ret struct {
+ HasAnyUser, HasOnlyOneUser bool
+}, err error,
+) {
+ res, err := db.GetEngine(ctx).Table(&User{}).Cols("id").Limit(2).Query()
+ if err != nil {
+ return ret, fmt.Errorf("error checking user existence: %w", err)
+ }
+ ret.HasAnyUser = len(res) != 0
+ ret.HasOnlyOneUser = len(res) == 1
+ return ret, nil
+}
+
// CountUsers returns number of users.
func CountUsers(ctx context.Context, opts *CountUserFilter) int64 {
return countUsers(ctx, opts)
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index e94e0ab9ca..4d1f7e7bf4 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -421,6 +421,7 @@ remember_me.compromised = The login token is not valid anymore which may indicat
forgot_password_title= Forgot Password
forgot_password = Forgot password?
need_account = Need an account?
+sign_up_tip = You are registering the first account in the system, which has administrator privileges. Please carefully remember your username and password. If you forget the username or password, please refer to the Gitea documentation to recover the account.
sign_up_now = Register now.
sign_up_successful = Account was successfully created. Welcome!
confirmation_mail_sent_prompt_ex = A new confirmation email has been sent to <b>%s</b>. Please check your inbox within the next %s to complete the registration process. If your registration email address is incorrect, you can sign in again and change it.
diff --git a/routers/install/install.go b/routers/install/install.go
index b9bc41dfcf..c1da79454a 100644
--- a/routers/install/install.go
+++ b/routers/install/install.go
@@ -601,5 +601,7 @@ func SubmitInstall(ctx *context.Context) {
// InstallDone shows the "post-install" page, makes it easier to develop the page.
// The name is not called as "PostInstall" to avoid misinterpretation as a handler for "POST /install"
func InstallDone(ctx *context.Context) { //nolint
+ hasUsers, _ := user_model.HasUsers(ctx)
+ ctx.Data["IsAccountCreated"] = hasUsers.HasAnyUser
ctx.HTML(http.StatusOK, tplPostInstall)
}
diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go
index 87edbc357b..94f75f69ff 100644
--- a/routers/web/auth/auth.go
+++ b/routers/web/auth/auth.go
@@ -421,9 +421,11 @@ func SignOut(ctx *context.Context) {
// SignUp render the register page
func SignUp(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_up")
-
ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up"
+ hasUsers, _ := user_model.HasUsers(ctx)
+ ctx.Data["IsFirstTimeRegistration"] = !hasUsers.HasAnyUser
+
oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, optional.Some(true))
if err != nil {
ctx.ServerError("UserSignUp", err)
@@ -610,7 +612,13 @@ func createUserInContext(ctx *context.Context, tpl templates.TplName, form any,
// sends a confirmation email if required.
func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.User) (ok bool) {
// Auto-set admin for the only user.
- if user_model.CountUsers(ctx, nil) == 1 {
+ hasUsers, err := user_model.HasUsers(ctx)
+ if err != nil {
+ ctx.ServerError("HasUsers", err)
+ return false
+ }
+ if hasUsers.HasOnlyOneUser {
+ // the only user is the one just created, will set it as admin
opts := &user_service.UpdateOptions{
IsActive: optional.Some(true),
IsAdmin: user_service.UpdateOptionFieldFromValue(true),
diff --git a/templates/post-install.tmpl b/templates/post-install.tmpl
index 0c9aa35c90..9baac4f84c 100644
--- a/templates/post-install.tmpl
+++ b/templates/post-install.tmpl
@@ -4,7 +4,7 @@
<!-- the "cup" has a handler, so move it a little leftward to make it visually in the center -->
<div class="tw-ml-[-30px]"><img width="160" src="{{AssetUrlPrefix}}/img/loading.png" alt aria-hidden="true"></div>
<div class="tw-my-[2em] tw-text-[18px]">
- <a id="goto-user-login" href="{{AppSubUrl}}/user/login">{{ctx.Locale.Tr "install.installing_desc"}}</a>
+ <a id="goto-after-install" href="{{AppSubUrl}}{{Iif .IsAccountCreated "/user/login" "/user/sign_up"}}">{{ctx.Locale.Tr "install.installing_desc"}}</a>
</div>
</div>
</div>
diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl
index d66568199d..a3f6e1471f 100644
--- a/templates/user/auth/signup_inner.tmpl
+++ b/templates/user/auth/signup_inner.tmpl
@@ -7,6 +7,9 @@
{{end}}
</h4>
<div class="ui attached segment">
+ {{if .IsFirstTimeRegistration}}
+ <p>{{ctx.Locale.Tr "auth.sign_up_tip"}}</p>
+ {{end}}
<form class="ui form" action="{{.SignUpLink}}" method="post">
{{.CsrfTokenHtml}}
{{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister)}}
diff --git a/web_src/js/features/install.ts b/web_src/js/features/install.ts
index 34df4757f9..ca4bcce881 100644
--- a/web_src/js/features/install.ts
+++ b/web_src/js/features/install.ts
@@ -104,7 +104,7 @@ function initPreInstall() {
}
function initPostInstall() {
- const el = document.querySelector('#goto-user-login');
+ const el = document.querySelector('#goto-after-install');
if (!el) return;
const targetUrl = el.getAttribute('href');