diff --git a/Dockerfile b/Dockerfile index d2029a8..d76895a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,22 +8,23 @@ WORKDIR /app COPY . . -RUN go env && CGO_ENABLED=0 go build -o next-terminal main.go +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories +RUN apk add gcc g++ +RUN go env && CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -a -ldflags '-linkmode external -extldflags "-static"' -o next-terminal main.go FROM guacamole/guacd:1.2.0 LABEL MAINTAINER="helloworld1024@foxmail.com" +RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list RUN apt-get update && apt-get -y install supervisor RUN mkdir -p /var/log/supervisor COPY --from=builder /app/supervisord.conf /etc/supervisor/conf.d/supervisord.conf -ENV MYSQL_HOSTNAME 127.0.0.1 -ENV MYSQL_PORT 3306 -ENV MYSQL_USERNAME mysql -ENV MYSQL_PASSWORD mysql -ENV MYSQL_DATABASE next_terminal +ENV DB sqlite +ENV SQLITE_FILE 'next-terminal.db' ENV SERVER_PORT 8088 +ENV SERVER_ADDR 0.0.0.0:$SERVER_PORT WORKDIR /usr/local/next-terminal diff --git a/config.yml b/config.yml index 097253e..62aa885 100644 --- a/config.yml +++ b/config.yml @@ -1,8 +1,11 @@ +db: mysql mysql: - hostname: 127.0.0.1 + hostname: 172.16.101.32 port: 3306 username: root - password: root - database: next_terminal + password: mysql + database: next-terminal +sqlite: + file: 'next-terminal.db' server: addr: 0.0.0.0:8088 \ No newline at end of file diff --git a/go.mod b/go.mod index d8d3ab3..4ef47a9 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,10 @@ require ( github.com/labstack/gommon v0.3.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pkg/sftp v1.12.0 - github.com/sirupsen/logrus v1.2.0 github.com/spf13/pflag v1.0.3 github.com/spf13/viper v1.7.1 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a gorm.io/driver/mysql v1.0.3 + gorm.io/driver/sqlite v1.1.4 // indirect gorm.io/gorm v1.20.7 ) diff --git a/go.sum b/go.sum index 7e3cf5b..c376c8a 100644 --- a/go.sum +++ b/go.sum @@ -135,6 +135,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= +github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -355,6 +357,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.0.3 h1:+JKBYPfn1tygR1/of/Fh2T8iwuVwzt+PEJmKaXzMQXg= gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI= +gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= +gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.7 h1:rMS4CL3pNmYq1V5/X+nHHjh1Dx6dnf27+Cai5zabo+M= gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= diff --git a/main.go b/main.go index aabada3..90287c2 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "github.com/labstack/gommon/log" "github.com/patrickmn/go-cache" "gorm.io/driver/mysql" + "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" "next-terminal/pkg/api" @@ -22,19 +23,27 @@ func main() { } func Run() error { - global.Config = config.SetupConfig() - var err error - dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", - global.Config.Mysql.Username, - global.Config.Mysql.Password, - global.Config.Mysql.Hostname, - global.Config.Mysql.Port, - global.Config.Mysql.Database, - ) - global.DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{ - Logger: logger.Default.LogMode(logger.Info), - }) + global.Config, err = config.SetupConfig() + if err != nil { + return err + } + + if global.Config.DB == "mysql" { + dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", + global.Config.Mysql.Username, + global.Config.Mysql.Password, + global.Config.Mysql.Hostname, + global.Config.Mysql.Port, + global.Config.Mysql.Database, + ) + global.DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Info), + }) + } else { + global.DB, err = gorm.Open(sqlite.Open(global.Config.Sqlite.File), &gorm.Config{}) + } + if err != nil { return err } diff --git a/pkg/api/account.go b/pkg/api/account.go index 73d914a..ed14a1f 100644 --- a/pkg/api/account.go +++ b/pkg/api/account.go @@ -13,6 +13,11 @@ type LoginAccount struct { Password string `json:"password"` } +type ChangePassword struct { + NewPassword string `json:"newPassword"` + OldPassword string `json:"oldPassword"` +} + func LoginEndpoint(c echo.Context) error { var loginAccount LoginAccount if err := c.Bind(&loginAccount); err != nil { @@ -21,10 +26,10 @@ func LoginEndpoint(c echo.Context) error { user, err := model.FindUserByUsername(loginAccount.Username) if err != nil { - return err + return Fail(c, -1, "您输入的账号或密码不正确") } if err := utils.Encoder.Match([]byte(user.Password), []byte(loginAccount.Password)); err != nil { - return err + return Fail(c, -1, "您输入的账号或密码不正确") } token := utils.UUID() @@ -43,7 +48,28 @@ func LogoutEndpoint(c echo.Context) error { } func ChangePasswordEndpoint(c echo.Context) error { - return nil + account, _ := GetCurrentAccount(c) + + var changePassword ChangePassword + if err := c.Bind(&changePassword); err != nil { + return err + } + + if err := utils.Encoder.Match([]byte(account.Password), []byte(changePassword.OldPassword)); err != nil { + return Fail(c, -1, "您输入的原密码不正确") + } + + passwd, err := utils.Encoder.Encode([]byte(changePassword.NewPassword)) + if err != nil { + return err + } + u := &model.User{ + Password: string(passwd), + } + + model.UpdateUserById(u, account.ID) + + return LogoutEndpoint(c) } func InfoEndpoint(c echo.Context) error { diff --git a/pkg/api/middleware.go b/pkg/api/middleware.go index 9145872..748b9ab 100644 --- a/pkg/api/middleware.go +++ b/pkg/api/middleware.go @@ -7,6 +7,16 @@ import ( "time" ) +func ErrorHandler(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + + if err := next(c); err != nil { + return Fail(c, 0, err.Error()) + } + return nil + } +} + func Auth(next echo.HandlerFunc) echo.HandlerFunc { urls := []string{"download", "recording", "login", "static", "favicon", "logo"} diff --git a/pkg/api/routes.go b/pkg/api/routes.go index 71e907c..6f9dec2 100644 --- a/pkg/api/routes.go +++ b/pkg/api/routes.go @@ -36,6 +36,7 @@ func SetupRoutes() *echo.Echo { AllowOrigins: []string{"*"}, AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete}, })) + e.Use(ErrorHandler) e.Use(Auth) e.POST("/login", LoginEndpoint) diff --git a/pkg/api/user.go b/pkg/api/user.go index 40cec03..a11d8eb 100644 --- a/pkg/api/user.go +++ b/pkg/api/user.go @@ -16,7 +16,7 @@ func UserCreateEndpoint(c echo.Context) error { var pass []byte var err error - if pass, err = utils.Encoder.Encode([]byte("admin")); err != nil { + if pass, err = utils.Encoder.Encode([]byte(item.Password)); err != nil { return err } item.Password = string(pass) diff --git a/pkg/config/config.go b/pkg/config/config.go index c2b7ae4..701c664 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,16 +1,16 @@ package config import ( - "log" "strings" - "github.com/spf13/pflag" "github.com/spf13/viper" ) type Config struct { + DB string Server *Server Mysql *Mysql + Sqlite *Sqlite } type Mysql struct { @@ -21,36 +21,31 @@ type Mysql struct { Database string } +type Sqlite struct { + File string +} + type Server struct { Addr string } -func SetupConfig() *Config { +func SetupConfig() (*Config, error) { viper.SetConfigName("config") - viper.SetConfigType("yaml") + viper.SetConfigType("yml") viper.AddConfigPath("/etc/next-terminal/") viper.AddConfigPath("$HOME/.next-terminal") viper.AddConfigPath(".") viper.AutomaticEnv() viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - //pflag.String("mysql.hostname", "127.0.0.1", "mysql hostname") - //pflag.Int("mysql.port", 3306, "mysql port") - //pflag.String("mysql.username", "mysql", "mysql username") - //pflag.String("mysql.password", "mysql", "mysql password") - //pflag.String("mysql.database", "next_terminal", "mysql database") - //pflag.String("server.addr", "0.0.0.0:8088", "server listen addr") - - pflag.Parse() - _ = viper.BindPFlags(pflag.CommandLine) - err := viper.ReadInConfig() if err != nil { - log.Fatal(err) + return nil, err } var config = &Config{ + DB: viper.GetString("db"), Mysql: &Mysql{ Hostname: viper.GetString("mysql.hostname"), Port: viper.GetInt("mysql.port"), @@ -58,10 +53,13 @@ func SetupConfig() *Config { Password: viper.GetString("mysql.password"), Database: viper.GetString("mysql.database"), }, + Sqlite: &Sqlite{ + File: viper.GetString("sqlite.file"), + }, Server: &Server{ Addr: viper.GetString("server.addr"), }, } - return config + return config, nil } diff --git a/supervisord.conf b/supervisord.conf index eb5981e..b6099d3 100644 --- a/supervisord.conf +++ b/supervisord.conf @@ -5,4 +5,4 @@ command=/usr/local/guacamole/sbin/guacd -b 0.0.0.0 -L info -f [program:next-terminal] ; command=/usr/local/next-terminal/next-terminal --mysql.hostname %(ENV_MYSQL_HOSTNAME)s --mysql.port %(ENV_MYSQL_PORT)s --mysql.username %(ENV_MYSQL_USERNAME)s --mysql.password %(ENV_MYSQL_PASSWORD)s --mysql.database %(ENV_MYSQL_DATABASE)s --server.addr 0.0.0.0:%(ENV_SERVER_PORT)s -command=/usr/local/next-terminal/next-terminal \ No newline at end of file +command=/usr/local/next-terminal/next-terminal --server.addr 0.0.0.0:%(ENV_SERVER_PORT)s \ No newline at end of file diff --git a/web/src/common/constants.js b/web/src/common/constants.js index b81685f..bdea679 100644 --- a/web/src/common/constants.js +++ b/web/src/common/constants.js @@ -1,12 +1,12 @@ // prod -export const server = ''; -export const wsServer = ''; -export const prefix = ''; +// export const server = ''; +// export const wsServer = ''; +// export const prefix = ''; // dev -// export const server = '//127.0.0.1:8088'; -// export const wsServer = 'ws://127.0.0.1:8088'; -// export const prefix = ''; +export const server = '//127.0.0.1:8088'; +export const wsServer = 'ws://127.0.0.1:8088'; +export const prefix = ''; // export const server = '//172.16.101.32:8080'; // export const wsServer = 'ws://172.16.101.32:8080'; diff --git a/web/src/components/Login.js b/web/src/components/Login.js index a98fb31..3da91d0 100644 --- a/web/src/components/Login.js +++ b/web/src/components/Login.js @@ -12,9 +12,20 @@ const {Title} = Typography; class LoginForm extends Component { state = { - inLogin: false + inLogin: false, + height: window.innerHeight, + width: window.innerWidth }; + componentDidMount() { + window.addEventListener('resize', () => { + this.setState({ + height: window.innerHeight, + width: window.innerWidth + }) + }); + } + handleSubmit = async params => { this.setState({ inLogin: true @@ -50,7 +61,8 @@ class LoginForm extends Component { render() { return ( -