Compare commits

..

9 Commits

Author SHA1 Message Date
Alf Sebastian Houge
0b715ef840 Fix warnings generated by go-staticcheck 2022-04-28 17:52:57 +02:00
Akhil Gupta
24105dbaaf Merge pull request #59 from meichthys/patch-1
remove whitespace from JWT_SECRET
2022-04-25 16:42:53 +05:30
Akhil Gupta
e3846634b5 Merge pull request #75 from AlfHou/icon-mobile
Add icon for mobile homescreens
2022-04-25 16:42:25 +05:30
Akhil Gupta
fd52c23636 Merge pull request #77 from AlfHou/mileage_on_odometer 2022-04-25 16:41:11 +05:30
Alf Sebastian Houge
20a1421576 Calculate mileage on odometer order instead of time 2022-03-15 14:26:46 +01:00
Alf Sebastian Houge
74e52c3e87 Change favicon to match mobile icon 2022-03-07 16:53:47 +01:00
Alf Sebastian Houge
1857bb0518 Change icon to gas pump icon instead of text 2022-03-07 10:41:28 +01:00
Alf Sebastian Houge
a729b5eb12 Add icon for mobile homescreens 2022-03-07 00:46:42 +01:00
MeIchthys
04f45fe385 remove whitespace from JWT_SECRET
When deploying with the whitespace around the `=`, docker complains.
2022-01-20 23:55:39 -05:00
12 changed files with 24 additions and 47 deletions

View File

@@ -35,7 +35,6 @@
- [Built With](#built-with) - [Built With](#built-with)
- [Features](#features) - [Features](#features)
- [Installation](#installation) - [Installation](#installation)
- [Contributing](#contributing)
- [License](#license) - [License](#license)
- [Roadmap](#roadmap) - [Roadmap](#roadmap)
- [Contact](#contact) - [Contact](#contact)
@@ -158,31 +157,6 @@ Once done you will be taken to the login page.
Go through the settings page once and change relevant settings before you start adding vehicles and expenses. Go through the settings page once and change relevant settings before you start adding vehicles and expenses.
## Contributing
### Dev Setup
If you want to contribute to the project you need to set it up
for development first.
Fork and clone the project. Once you have it on your own machine,
open up a terminal and navigate to the `server/` directory.
In the `server/` directory run the command `go run main.go`.
After some initial
setup, the server should be listening on at port `3000`.
Next, open a new terminal. Navigate to the `ui/` directory and run `npm install`.
This will install all the dependencies for the frontend.
After the command is done running, run `npm run dev`. After some output, the
frontend should be accessible at `http://localhost:8080`.
If you are sent straight to the login screen, try closing the page and opening
it again. You should be greeted with a setup wizard the first time you run the
project.
Now, simply follow the instructions in order to set up your fresh install.
## License ## License
Distributed under the GPL-3.0 License. See `LICENSE` for more information. Distributed under the GPL-3.0 License. See `LICENSE` for more information.

View File

@@ -4,7 +4,7 @@ services:
image: akhilrex/hammond image: akhilrex/hammond
container_name: hammond container_name: hammond
environment: environment:
- JWT_SECRET = somethingverystrong - JWT_SECRET=somethingverystrong
volumes: volumes:
- /path/to/config:/config - /path/to/config:/config
- /path/to/data:/assets - /path/to/data:/assets

View File

@@ -94,17 +94,17 @@ func userLogin(c *gin.Context) {
user, err := db.FindOneUser(&db.User{Email: loginRequest.Email}) user, err := db.FindOneUser(&db.User{Email: loginRequest.Email})
if err != nil { if err != nil {
c.JSON(http.StatusForbidden, common.NewError("login", errors.New("Not Registered email or invalid password"))) c.JSON(http.StatusForbidden, common.NewError("login", errors.New("not Registered email or invalid password")))
return return
} }
if user.CheckPassword(loginRequest.Password) != nil { if user.CheckPassword(loginRequest.Password) != nil {
c.JSON(http.StatusForbidden, common.NewError("login", errors.New("Not Registered email or invalid password"))) c.JSON(http.StatusForbidden, common.NewError("login", errors.New("not Registered email or invalid password")))
return return
} }
if user.IsDisabled { if user.IsDisabled {
c.JSON(http.StatusForbidden, common.NewError("login", errors.New("Your user has been disabled by the admin. Please contact them to get it re-enabled."))) c.JSON(http.StatusForbidden, common.NewError("login", errors.New("your user has been disabled by the admin. Please contact them to get it re-enabled")))
return return
} }
UpdateContextUserModel(c, user.ID) UpdateContextUserModel(c, user.ID)
@@ -170,16 +170,16 @@ func changePassword(c *gin.Context) {
user, err := service.GetUserById(c.GetString("userId")) user, err := service.GetUserById(c.GetString("userId"))
if err != nil { if err != nil {
c.JSON(http.StatusForbidden, common.NewError("changePassword", errors.New("Not Registered email or invalid password"))) c.JSON(http.StatusForbidden, common.NewError("changePassword", errors.New("not Registered email or invalid password")))
return return
} }
if user.CheckPassword(request.OldPassword) != nil { if user.CheckPassword(request.OldPassword) != nil {
c.JSON(http.StatusForbidden, common.NewError("changePassword", errors.New("Incorrect old password"))) c.JSON(http.StatusForbidden, common.NewError("changePassword", errors.New("incorrect old password")))
return return
} }
user.SetPassword(request.NewPassword) user.SetPassword(request.NewPassword)
success, err := service.UpdatePassword(user.ID, request.NewPassword) success, _ := service.UpdatePassword(user.ID, request.NewPassword)
c.JSON(http.StatusOK, success) c.JSON(http.StatusOK, success)
} }

View File

@@ -23,8 +23,8 @@ func stripBearerPrefixFromTokenString(tok string) (string, error) {
// Extract token from Authorization header // Extract token from Authorization header
// Uses PostExtractionFilter to strip "TOKEN " prefix from header // Uses PostExtractionFilter to strip "TOKEN " prefix from header
var AuthorizationHeaderExtractor = &request.PostExtractionFilter{ var AuthorizationHeaderExtractor = &request.PostExtractionFilter{
request.HeaderExtractor{"Authorization"}, Extractor: request.HeaderExtractor{"Authorization"},
stripBearerPrefixFromTokenString, Filter: stripBearerPrefixFromTokenString,
} }
// Extractor for OAuth2 access tokens. Looks in 'Authorization' // Extractor for OAuth2 access tokens. Looks in 'Authorization'

View File

@@ -51,7 +51,7 @@ func migrate(c *gin.Context) {
canMigrate, _, _ := db.CanMigrate(request.Url) canMigrate, _, _ := db.CanMigrate(request.Url)
if !canMigrate { if !canMigrate {
c.JSON(http.StatusBadRequest, fmt.Errorf("cannot migrate database. please check connection string.")) c.JSON(http.StatusBadRequest, fmt.Errorf("cannot migrate database. please check connection string"))
return return
} }

View File

@@ -397,7 +397,7 @@ func deleteVehicle(c *gin.Context) {
return return
} }
if !canDelete { if !canDelete {
c.JSON(http.StatusUnprocessableEntity, common.NewError("shareVehicle", errors.New("You are not allowed to delete this vehicle."))) c.JSON(http.StatusUnprocessableEntity, common.NewError("shareVehicle", errors.New("you are not allowed to delete this vehicle")))
return return
} }
err = service.DeleteVehicle(searchByIdQuery.Id) err = service.DeleteVehicle(searchByIdQuery.Id)

View File

@@ -117,7 +117,7 @@ func UnshareVehicle(vehicleId, userId string) error {
return nil return nil
} }
if mapping.IsOwner { if mapping.IsOwner {
return fmt.Errorf("Cannot unshare owner") return fmt.Errorf("cannot unshare owner")
} }
result := DB.Where("id=?", mapping.ID).Delete(&UserVehicle{}) result := DB.Where("id=?", mapping.ID).Delete(&UserVehicle{})
return result.Error return result.Error
@@ -332,8 +332,7 @@ func UnlockMissedJobs() {
if (job.Date == time.Time{}) { if (job.Date == time.Time{}) {
continue continue
} }
var duration time.Duration var duration = time.Duration(job.Duration)
duration = time.Duration(job.Duration)
d := job.Date.Add(time.Minute * duration) d := job.Date.Add(time.Minute * duration)
if d.Before(time.Now()) { if d.Before(time.Now()) {
fmt.Println(job.Name + " is unlocked") fmt.Println(job.Name + " is unlocked")

View File

@@ -3,7 +3,6 @@ package service
import ( import (
"archive/tar" "archive/tar"
"compress/gzip" "compress/gzip"
"errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@@ -126,14 +125,14 @@ func CreateBackup() (string, error) {
tarballFilePath := path.Join(folder, backupFileName) tarballFilePath := path.Join(folder, backupFileName)
file, err := os.Create(tarballFilePath) file, err := os.Create(tarballFilePath)
if err != nil { if err != nil {
return "", errors.New(fmt.Sprintf("Could not create tarball file '%s', got error '%s'", tarballFilePath, err.Error())) return "", fmt.Errorf("could not create tarball file '%s', got error '%s'", tarballFilePath, err.Error())
} }
defer file.Close() defer file.Close()
dbPath := path.Join(configPath, "hammond.db") dbPath := path.Join(configPath, "hammond.db")
_, err = os.Stat(dbPath) _, err = os.Stat(dbPath)
if err != nil { if err != nil {
return "", errors.New(fmt.Sprintf("Could not find db file '%s', got error '%s'", dbPath, err.Error())) return "", fmt.Errorf("could not find db file '%s', got error '%s'", dbPath, err.Error())
} }
gzipWriter := gzip.NewWriter(file) gzipWriter := gzip.NewWriter(file)
defer gzipWriter.Close() defer gzipWriter.Close()
@@ -151,13 +150,13 @@ func CreateBackup() (string, error) {
func addFileToTarWriter(filePath string, tarWriter *tar.Writer) error { func addFileToTarWriter(filePath string, tarWriter *tar.Writer) error {
file, err := os.Open(filePath) file, err := os.Open(filePath)
if err != nil { if err != nil {
return errors.New(fmt.Sprintf("Could not open file '%s', got error '%s'", filePath, err.Error())) return fmt.Errorf("could not open file '%s', got error '%s'", filePath, err.Error())
} }
defer file.Close() defer file.Close()
stat, err := file.Stat() stat, err := file.Stat()
if err != nil { if err != nil {
return errors.New(fmt.Sprintf("Could not get stat for file '%s', got error '%s'", filePath, err.Error())) return fmt.Errorf("could not get stat for file '%s', got error '%s'", filePath, err.Error())
} }
header := &tar.Header{ header := &tar.Header{
@@ -169,12 +168,12 @@ func addFileToTarWriter(filePath string, tarWriter *tar.Writer) error {
err = tarWriter.WriteHeader(header) err = tarWriter.WriteHeader(header)
if err != nil { if err != nil {
return errors.New(fmt.Sprintf("Could not write header for file '%s', got error '%s'", filePath, err.Error())) return fmt.Errorf("could not write header for file '%s', got error '%s'", filePath, err.Error())
} }
_, err = io.Copy(tarWriter, file) _, err = io.Copy(tarWriter, file)
if err != nil { if err != nil {
return errors.New(fmt.Sprintf("Could not copy the file '%s' data to the tarball, got error '%s'", filePath, err.Error())) return fmt.Errorf("could not copy the file '%s' data to the tarball, got error '%s'", filePath, err.Error())
} }
return nil return nil

View File

@@ -1,6 +1,7 @@
package service package service
import ( import (
"sort"
"time" "time"
"github.com/akhilrex/hammond/db" "github.com/akhilrex/hammond/db"
@@ -15,6 +16,9 @@ func GetMileageByVehicleId(vehicleId string, since time.Time) (mileage []models.
fillups := make([]db.Fillup, len(*data)) fillups := make([]db.Fillup, len(*data))
copy(fillups, *data) copy(fillups, *data)
sort.Slice(fillups, func(i, j int) bool {
return fillups[i].OdoReading > fillups[j].OdoReading
})
var mileages []models.MileageModel var mileages []models.MileageModel

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 895 B

View File

@@ -5,6 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="shortcut icon" href="<%= webpackConfig.output.publicPath %>hammond.png" /> <link rel="shortcut icon" href="<%= webpackConfig.output.publicPath %>hammond.png" />
<link rel="apple-touch-icon" href="<%= webpackConfig.output.publicPath %>touch-icon.png" />
<title><%= webpackConfig.name %></title> <title><%= webpackConfig.name %></title>
</head> </head>
<body> <body>

BIN
ui/public/touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB