Merge pull request #899 from 0xJacky/feat/cli-reset-pwd

Feat/cli reset pwd
This commit is contained in:
Jacky 2025-03-03 12:03:31 +08:00 committed by GitHub
commit 78052ea0f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 299 additions and 2 deletions

View file

@ -3,6 +3,7 @@ package user
import (
"github.com/0xJacky/Nginx-UI/internal/user"
"github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy"
@ -40,6 +41,12 @@ func InitManageUserRouter(g *gin.RouterGroup) {
}
})
c.BeforeDecodeHook(encryptPassword)
c.ExecutedHook(func(ctx *cosy.Ctx[model.User]) {
if ctx.Payload["password"] != "" {
a := query.AuthToken
_, _ = a.Where(a.UserID.Eq(ctx.ID)).Delete()
}
})
})
c.DestroyHook(func(c *cosy.Ctx[model.User]) {

View file

@ -3,7 +3,9 @@ import VOtpInput from 'vue3-otp-input'
const emit = defineEmits(['onComplete'])
const data = defineModel<string>()
const data = defineModel<string>({
default: '',
})
// eslint-disable-next-line vue/require-typed-ref
const refOtp = ref()

View file

@ -190,7 +190,6 @@ async function handlePasskeyLogin() {
<AButton
v-if="has_casdoor"
block
html-type="submit"
:loading="loading"
class="mb-5"
@click="loginWithCasdoor"

View file

@ -64,6 +64,7 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
collapsed: false,
items: [
{ text: 'Nginx Proxy Example', link: '/guide/nginx-proxy-example' },
{ text: 'Reset Password', link: '/guide/reset-password' },
{ text: 'License', link: '/guide/license' }
]
}

View file

@ -69,6 +69,7 @@ export const zhCNConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
collapsed: false,
items: [
{ text: 'Nginx 代理示例', link: '/zh_CN/guide/nginx-proxy-example' },
{ text: '重置密码', link: '/zh_CN/guide/reset-password' },
{ text: '开源协议', link: '/zh_CN/guide/license' }
]
}

View file

@ -69,6 +69,7 @@ export const zhTWConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
collapsed: false,
items: [
{ text: 'Nginx 代理示例', link: '/zh_TW/guide/nginx-proxy-example' },
{ text: '重置密碼', link: '/zh_TW/guide/reset-password' },
{ text: '開源協議', link: '/zh_TW/guide/license' }
]
}

View file

@ -0,0 +1,61 @@
# Reset Initial User Password
The `reset-password` command allows you to reset the initial administrator account's password to a randomly generated 12-character password that includes uppercase letters, lowercase letters, numbers, and special symbols.
## Usage
To reset the initial user's password, run:
```bash
nginx-ui reset-password --config=/path/to/app.ini
```
The command will:
1. Generate a secure random password (12 characters)
2. Reset the password for the initial user account (user ID 1)
3. Output the new password in the application logs
## Parameters
- `--config`: (Required) Path to the Nginx UI configuration file
## Example
```bash
# Reset the password using the default config file location
nginx-ui reset-password --config=/path/to/app.ini
# The output will include the generated password
2025-03-03 03:24:41 INFO user/reset_password.go:52 confPath: ../app.ini
2025-03-03 03:24:41 INFO user/reset_password.go:59 dbPath: ../database.db
2025-03-03 03:24:41 INFO user/reset_password.go:92 User: root, Password: X&K^(X0m(E&&
```
## Configuration File Location
- If you installed Nginx UI using the Linux one-click installation script, the configuration file is located at:
```
/usr/local/etc/nginx-ui/app.ini
```
You can directly use the following command:
```bash
nginx-ui reset-password --config /usr/local/etc/nginx-ui/app.ini
```
## Docker Usage
If you're running Nginx UI in a Docker container, you need to use the `docker exec` command:
```bash
docker exec -it <nginx-ui-container> nginx-ui reset-password --config=/etc/nginx-ui/app.ini
```
Replace `<nginx-ui-container>` with your actual container name or ID.
## Notes
- This command is useful if you've forgotten the initial administrator password
- The new password will be displayed in the logs, so be sure to copy it immediately
- You must have access to the server's command line to use this feature
- The database file must exist for this command to work

View file

@ -0,0 +1,61 @@
# 重置初始用户密码
`reset-password` 命令允许您将初始管理员账户的密码重置为随机生成的12位密码包含大写字母、小写字母、数字和特殊符号。
## 使用方法
要重置初始用户的密码,请运行:
```bash
nginx-ui reset-password --config=/path/to/app.ini
```
此命令将:
1. 生成一个安全的随机密码12个字符
2. 重置初始用户账户用户ID 1的密码
3. 在应用程序日志中输出新密码
## 参数
- `--config`必填Nginx UI 配置文件的路径
## 示例
```bash
# 使用默认配置文件位置重置密码
nginx-ui reset-password --config=/path/to/app.ini
# 输出将包含生成的密码
2025-03-03 03:24:41 INFO user/reset_password.go:52 confPath: ../app.ini
2025-03-03 03:24:41 INFO user/reset_password.go:59 dbPath: ../database.db
2025-03-03 03:24:41 INFO user/reset_password.go:92 User: root, Password: X&K^(X0m(E&&
```
## 配置文件位置
- 如果您使用 Linux 一键安装脚本安装的 Nginx UI配置文件位于
```
/usr/local/etc/nginx-ui/app.ini
```
您可以直接使用以下命令:
```bash
nginx-ui reset-password --config /usr/local/etc/nginx-ui/app.ini
```
## Docker 使用方法
如果您在 Docker 容器中运行 Nginx UI需要使用 `docker exec` 命令:
```bash
docker exec -it <nginx-ui-container> nginx-ui reset-password --config=/etc/nginx-ui/app.ini
```
请将 `<nginx-ui-container>` 替换为您实际的容器名称或 ID。
## 注意事项
- 如果您忘记了初始管理员密码,此命令很有用
- 新密码将显示在日志中,请确保立即复制它
- 您必须有权访问服务器的命令行才能使用此功能
- 数据库文件必须存在才能使此命令正常工作

View file

@ -0,0 +1,61 @@
# 重置初始用戶密碼
`reset-password` 命令允許您將初始管理員賬戶的密碼重置為隨機生成的12位密碼包含大寫字母、小寫字母、數字和特殊符號。
## 使用方法
要重置初始用戶的密碼,請運行:
```bash
nginx-ui reset-password --config=/path/to/app.ini
```
此命令將:
1. 生成一個安全的隨機密碼12個字符
2. 重置初始用戶賬戶用戶ID 1的密碼
3. 在應用程序日誌中輸出新密碼
## 參數
- `--config`必填Nginx UI 配置文件的路徑
## 示例
```bash
# 使用默認配置文件位置重置密碼
nginx-ui reset-password --config=/path/to/app.ini
# 輸出將包含生成的密碼
2025-03-03 03:24:41 INFO user/reset_password.go:52 confPath: ../app.ini
2025-03-03 03:24:41 INFO user/reset_password.go:59 dbPath: ../database.db
2025-03-03 03:24:41 INFO user/reset_password.go:92 User: root, Password: X&K^(X0m(E&&
```
## 配置文件位置
- 如果您使用 Linux 一鍵安裝腳本安裝的 Nginx UI配置文件位於
```
/usr/local/etc/nginx-ui/app.ini
```
您可以直接使用以下命令:
```bash
nginx-ui reset-password --config /usr/local/etc/nginx-ui/app.ini
```
## Docker 使用方法
如果您在 Docker 容器中運行 Nginx UI需要使用 `docker exec` 命令:
```bash
docker exec -it <nginx-ui-container> nginx-ui reset-password --config=/etc/nginx-ui/app.ini
```
請將 `<nginx-ui-container>` 替換為您實際的容器名稱或 ID。
## 注意事項
- 如果您忘記了初始管理員密碼,此命令很有用
- 新密碼將顯示在日誌中,請確保立即複製它
- 您必須有權訪問服務器的命令行才能使用此功能
- 數據庫文件必須存在才能使此命令正常工作

View file

@ -5,6 +5,7 @@ import (
"log"
"os"
"github.com/0xJacky/Nginx-UI/internal/user"
"github.com/0xJacky/Nginx-UI/internal/version"
"github.com/urfave/cli/v3"
)
@ -24,6 +25,11 @@ func NewAppCmd() *cli.Command {
return nil
},
},
{
Name: "reset-password",
Usage: "Reset the initial user password",
Action: user.ResetInitUserPassword,
},
},
Flags: []cli.Flag{
&cli.StringFlag{

View file

@ -0,0 +1,97 @@
package user
import (
"context"
"crypto/rand"
"math/big"
"os"
"path"
"github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/uozi-tech/cosy"
sqlite "github.com/uozi-tech/cosy-driver-sqlite"
"github.com/uozi-tech/cosy/logger"
cSettings "github.com/uozi-tech/cosy/settings"
"github.com/urfave/cli/v3"
"golang.org/x/crypto/bcrypt"
)
var (
ErrConfigNotFound = errors.New("config not found")
ErrDBFileNotFound = errors.New("db file not found")
ErrInitUserNotExists = errors.New("init user not exists")
)
func generateRandomPassword(length int) (string, error) {
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+"
password := make([]byte, length)
charsetLength := big.NewInt(int64(len(charset)))
for i := 0; i < length; i++ {
randomIndex, err := rand.Int(rand.Reader, charsetLength)
if err != nil {
return "", err
}
password[i] = charset[randomIndex.Int64()]
}
return string(password), nil
}
func ResetInitUserPassword(ctx context.Context, command *cli.Command) error {
confPath := command.String("config")
settings.Init(confPath)
cSettings.ServerSettings.RunMode = gin.ReleaseMode
logger.Init(cSettings.ServerSettings.RunMode)
logger.Infof("confPath: %s", confPath)
if _, err := os.Stat(confPath); os.IsNotExist(err) {
return ErrConfigNotFound
}
dbPath := path.Join(path.Dir(confPath), settings.DatabaseSettings.Name+".db")
logger.Infof("dbPath: %s", dbPath)
// check if db file exists
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
return ErrDBFileNotFound
}
db := cosy.InitDB(sqlite.Open(path.Dir(cSettings.ConfPath), settings.DatabaseSettings))
model.Use(db)
query.Init(db)
u := query.User
user, err := u.FirstByID(1)
if err != nil {
return ErrInitUserNotExists
}
pwd, err := generateRandomPassword(12)
if err != nil {
return err
}
pwdBytes, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
if err != nil {
return err
}
_, err = u.Where(u.ID.Eq(1)).Updates(&model.User{
Password: string(pwdBytes),
})
if err != nil {
return err
}
a := query.AuthToken
_, _ = a.Where(a.UserID.Eq(1)).Delete()
logger.Infof("User: %s, Password: %s", user.Name, pwd)
return nil
}