mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 02:15:48 +02:00
Merge pull request #899 from 0xJacky/feat/cli-reset-pwd
Feat/cli reset pwd
This commit is contained in:
commit
78052ea0f0
11 changed files with 299 additions and 2 deletions
|
@ -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]) {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -190,7 +190,6 @@ async function handlePasskeyLogin() {
|
|||
<AButton
|
||||
v-if="has_casdoor"
|
||||
block
|
||||
html-type="submit"
|
||||
:loading="loading"
|
||||
class="mb-5"
|
||||
@click="loginWithCasdoor"
|
||||
|
|
|
@ -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' }
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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' }
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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' }
|
||||
]
|
||||
}
|
||||
|
|
61
docs/guide/reset-password.md
Normal file
61
docs/guide/reset-password.md
Normal 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
|
61
docs/zh_CN/guide/reset-password.md
Normal file
61
docs/zh_CN/guide/reset-password.md
Normal 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。
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 如果您忘记了初始管理员密码,此命令很有用
|
||||
- 新密码将显示在日志中,请确保立即复制它
|
||||
- 您必须有权访问服务器的命令行才能使用此功能
|
||||
- 数据库文件必须存在才能使此命令正常工作
|
61
docs/zh_TW/guide/reset-password.md
Normal file
61
docs/zh_TW/guide/reset-password.md
Normal 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。
|
||||
|
||||
## 注意事項
|
||||
|
||||
- 如果您忘記了初始管理員密碼,此命令很有用
|
||||
- 新密碼將顯示在日誌中,請確保立即複製它
|
||||
- 您必須有權訪問服務器的命令行才能使用此功能
|
||||
- 數據庫文件必須存在才能使此命令正常工作
|
|
@ -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{
|
||||
|
|
97
internal/user/reset_password.go
Normal file
97
internal/user/reset_password.go
Normal 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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue