Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

feat: password reset emails #832

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/partial-frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ jobs:
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v3.0.0
with:
version: 6.0.2
version: 9

- name: Install dependencies
run: pnpm install --shamefully-hoist
Expand Down Expand Up @@ -46,18 +50,18 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.21"
go-version: "1.22"

- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20

- uses: pnpm/action-setup@v3.0.0
with:
version: 6.0.2
version: 9

- name: Install dependencies
run: pnpm install
run: pnpm install --shamefully-hoist
working-directory: frontend

- name: Run Integration Tests
Expand Down
11 changes: 11 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ env:
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_pragma=busy_timeout=1000&_pragma=journal_mode=WAL&_fk=1
HBOX_OPTIONS_ALLOW_REGISTRATION: true
UNSAFE_DISABLE_PASSWORD_PROJECTION: "yes_i_am_sure"
HBOX_MAILER_HOST: 127.0.0.1
HBOX_MAILER_PORT: 1025
HBOX_MAILER_USERNAME: c836555d57d205
HBOX_MAILER_PASSWORD: 3ff2f9986f3cff
HBOX_MAILER_FROM: info@example.com
tasks:
setup:
desc: Install development dependencies
Expand Down Expand Up @@ -79,6 +84,12 @@ tasks:
cmds:
- go mod tidy

go:fmt:
desc: Runs go fmt on the backend
dir: backend
cmds:
- gofumpt -w .

go:lint:
desc: Runs golangci-lint
dir: backend
Expand Down
9 changes: 6 additions & 3 deletions backend/.golangci.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
run:
timeout: 10m
skip-dirs:
- internal/data/ent.*
linters-settings:
errcheck:
exclude-functions:
- (net/http.ResponseWriter).Write
goconst:
min-len: 5
min-occurrences: 5
Expand Down Expand Up @@ -71,4 +72,6 @@ linters:
- sqlclosecheck
issues:
exclude-use-default: false
fix: true
fix: false
exclude-dirs:
- internal/data/ent.*
4 changes: 2 additions & 2 deletions backend/app/api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

type app struct {
conf *config.Config
mailer mailer.Mailer
mailer *mailer.Mailer
db *ent.Client
repos *repo.AllRepos
services *services.AllServices
Expand All @@ -23,7 +23,7 @@ func new(conf *config.Config) *app {
conf: conf,
}

s.mailer = mailer.Mailer{
s.mailer = &mailer.Mailer{
Host: s.conf.Mailer.Host,
Port: s.conf.Mailer.Port,
Username: s.conf.Mailer.Username,
Expand Down
4 changes: 1 addition & 3 deletions backend/app/api/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,18 @@ func (a *app) SetupDemo() {
_, err = a.services.User.RegisterUser(ctx, registration)
if err != nil {
log.Err(err).Msg("Failed to register demo user")
log.Fatal().Msg("Failed to setup demo")
log.Fatal().Msg("Failed to setup demo") // nolint
}

token, err := a.services.User.Login(ctx, registration.Email, registration.Password, false)
if err != nil {
log.Err(err).Msg("Failed to login demo user")
log.Fatal().Msg("Failed to setup demo")
return
}
self, err := a.services.User.GetSelf(ctx, token.Raw)
if err != nil {
log.Err(err).Msg("Failed to get self")
log.Fatal().Msg("Failed to setup demo")
return
}

_, err = a.services.Items.CsvImport(ctx, self.GroupID, strings.NewReader(csvText))
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func (ctrl *V1Controller) HandleCacheWS() errchain.HandlerFunc {

m.HandleConnect(func(s *melody.Session) {
auth := services.NewContext(s.Request.Context())
s.Set("gid", auth.GID)
s.Set("gid", auth.GroupID)
})

factory := func(e string) func(data any) {
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func actionHandlerFactory(ref string, fn func(context.Context, uuid.UUID) (int,
return func(w http.ResponseWriter, r *http.Request) error {
ctx := services.NewContext(r.Context())

totalCompleted, err := fn(ctx, ctx.GID)
totalCompleted, err := fn(ctx, ctx.GroupID)
if err != nil {
log.Err(err).Str("action_ref", ref).Msg("failed to run action")
return validate.NewRequestError(err, http.StatusInternalServerError)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (ctrl *V1Controller) HandleAssetGet() errchain.HandlerFunc {
}
}

items, err := ctrl.repo.Items.QueryByAssetID(r.Context(), ctx.GID, repo.AssetID(assetID), int(page), int(pageSize))
items, err := ctrl.repo.Items.QueryByAssetID(r.Context(), ctx.GroupID, repo.AssetID(assetID), int(page), int(pageSize))
if err != nil {
log.Err(err).Msg("failed to get item")
return validate.NewRequestError(err, http.StatusInternalServerError)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type (
func (ctrl *V1Controller) HandleGroupGet() errchain.HandlerFunc {
fn := func(r *http.Request) (repo.Group, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Groups.GroupByID(auth, auth.GID)
return ctrl.repo.Groups.GroupByID(auth, auth.GroupID)
}

return adapters.Command(fn, http.StatusOK)
Expand Down
22 changes: 11 additions & 11 deletions backend/app/api/handlers/v1/v1_ctrl_items.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) error {
ctx := services.NewContext(r.Context())

items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GID, extractQuery(r))
items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GroupID, extractQuery(r))
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{
Expand All @@ -105,12 +105,12 @@ func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleItemFullPath() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) ([]repo.ItemPath, error) {
auth := services.NewContext(r.Context())
item, err := ctrl.repo.Items.GetOneByGroup(auth, auth.GID, ID)
item, err := ctrl.repo.Items.GetOneByGroup(auth, auth.GroupID, ID)
if err != nil {
return nil, err
}

paths, err := ctrl.repo.Locations.PathForLoc(auth, auth.GID, item.Location.ID)
paths, err := ctrl.repo.Locations.PathForLoc(auth, auth.GroupID, item.Location.ID)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -165,7 +165,7 @@ func (ctrl *V1Controller) HandleItemGet() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (repo.ItemOut, error) {
auth := services.NewContext(r.Context())

return ctrl.repo.Items.GetOneByGroup(auth, auth.GID, ID)
return ctrl.repo.Items.GetOneByGroup(auth, auth.GroupID, ID)
}

return adapters.CommandID("id", fn, http.StatusOK)
Expand All @@ -183,7 +183,7 @@ func (ctrl *V1Controller) HandleItemGet() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleItemDelete() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
auth := services.NewContext(r.Context())
err := ctrl.repo.Items.DeleteByGroup(auth, auth.GID, ID)
err := ctrl.repo.Items.DeleteByGroup(auth, auth.GroupID, ID)
return nil, err
}

Expand All @@ -205,7 +205,7 @@ func (ctrl *V1Controller) HandleItemUpdate() errchain.HandlerFunc {
auth := services.NewContext(r.Context())

body.ID = ID
return ctrl.repo.Items.UpdateByGroup(auth, auth.GID, body)
return ctrl.repo.Items.UpdateByGroup(auth, auth.GroupID, body)
}

return adapters.ActionID("id", fn, http.StatusOK)
Expand All @@ -226,12 +226,12 @@ func (ctrl *V1Controller) HandleItemPatch() errchain.HandlerFunc {
auth := services.NewContext(r.Context())

body.ID = ID
err := ctrl.repo.Items.Patch(auth, auth.GID, ID, body)
err := ctrl.repo.Items.Patch(auth, auth.GroupID, ID, body)
if err != nil {
return repo.ItemOut{}, err
}

return ctrl.repo.Items.GetOneByGroup(auth, auth.GID, ID)
return ctrl.repo.Items.GetOneByGroup(auth, auth.GroupID, ID)
}

return adapters.ActionID("id", fn, http.StatusOK)
Expand All @@ -249,7 +249,7 @@ func (ctrl *V1Controller) HandleItemPatch() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleGetAllCustomFieldNames() errchain.HandlerFunc {
fn := func(r *http.Request) ([]string, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Items.GetAllCustomFieldNames(auth, auth.GID)
return ctrl.repo.Items.GetAllCustomFieldNames(auth, auth.GroupID)
}

return adapters.Command(fn, http.StatusOK)
Expand All @@ -271,7 +271,7 @@ func (ctrl *V1Controller) HandleGetAllCustomFieldValues() errchain.HandlerFunc {

fn := func(r *http.Request, q query) ([]string, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Items.GetAllCustomFieldValues(auth, auth.GID, q.Field)
return ctrl.repo.Items.GetAllCustomFieldValues(auth, auth.GroupID, q.Field)
}

return adapters.Query(fn, http.StatusOK)
Expand Down Expand Up @@ -323,7 +323,7 @@ func (ctrl *V1Controller) HandleItemsExport() errchain.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) error {
ctx := services.NewContext(r.Context())

csvData, err := ctrl.svc.Items.ExportTSV(r.Context(), ctx.GID)
csvData, err := ctrl.svc.Items.ExportTSV(r.Context(), ctx.GroupID)
if err != nil {
log.Err(err).Msg("failed to export items")
return validate.NewRequestError(err, http.StatusInternalServerError)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_items_attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (ctrl *V1Controller) handleItemAttachmentsHandler(w http.ResponseWriter, r

// Delete Attachment Handler
case http.MethodDelete:
err = ctrl.svc.Items.AttachmentDelete(r.Context(), ctx.GID, ID, attachmentID)
err = ctrl.svc.Items.AttachmentDelete(r.Context(), ctx.GroupID, ID, attachmentID)
if err != nil {
log.Err(err).Msg("failed to delete attachment")
return validate.NewRequestError(err, http.StatusInternalServerError)
Expand Down
10 changes: 5 additions & 5 deletions backend/app/api/handlers/v1/v1_ctrl_labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
fn := func(r *http.Request) ([]repo.LabelSummary, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Labels.GetAll(auth, auth.GID)
return ctrl.repo.Labels.GetAll(auth, auth.GroupID)
}

return adapters.Command(fn, http.StatusOK)
Expand All @@ -39,7 +39,7 @@ func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLabelsCreate() errchain.HandlerFunc {
fn := func(r *http.Request, data repo.LabelCreate) (repo.LabelOut, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Labels.Create(auth, auth.GID, data)
return ctrl.repo.Labels.Create(auth, auth.GroupID, data)
}

return adapters.Action(fn, http.StatusCreated)
Expand All @@ -57,7 +57,7 @@ func (ctrl *V1Controller) HandleLabelsCreate() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLabelDelete() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
auth := services.NewContext(r.Context())
err := ctrl.repo.Labels.DeleteByGroup(auth, auth.GID, ID)
err := ctrl.repo.Labels.DeleteByGroup(auth, auth.GroupID, ID)
return nil, err
}

Expand All @@ -76,7 +76,7 @@ func (ctrl *V1Controller) HandleLabelDelete() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLabelGet() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (repo.LabelOut, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Labels.GetOneByGroup(auth, auth.GID, ID)
return ctrl.repo.Labels.GetOneByGroup(auth, auth.GroupID, ID)
}

return adapters.CommandID("id", fn, http.StatusOK)
Expand All @@ -95,7 +95,7 @@ func (ctrl *V1Controller) HandleLabelUpdate() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID, data repo.LabelUpdate) (repo.LabelOut, error) {
auth := services.NewContext(r.Context())
data.ID = ID
return ctrl.repo.Labels.UpdateByGroup(auth, auth.GID, data)
return ctrl.repo.Labels.UpdateByGroup(auth, auth.GroupID, data)
}

return adapters.ActionID("id", fn, http.StatusOK)
Expand Down
12 changes: 6 additions & 6 deletions backend/app/api/handlers/v1/v1_ctrl_locations.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
fn := func(r *http.Request, query repo.TreeQuery) ([]repo.TreeItem, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Locations.Tree(auth, auth.GID, query)
return ctrl.repo.Locations.Tree(auth, auth.GroupID, query)
}

return adapters.Query(fn, http.StatusOK)
Expand All @@ -40,7 +40,7 @@ func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
fn := func(r *http.Request, q repo.LocationQuery) ([]repo.LocationOutCount, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Locations.GetAll(auth, auth.GID, q)
return ctrl.repo.Locations.GetAll(auth, auth.GroupID, q)
}

return adapters.Query(fn, http.StatusOK)
Expand All @@ -58,7 +58,7 @@ func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLocationCreate() errchain.HandlerFunc {
fn := func(r *http.Request, createData repo.LocationCreate) (repo.LocationOut, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Locations.Create(auth, auth.GID, createData)
return ctrl.repo.Locations.Create(auth, auth.GroupID, createData)
}

return adapters.Action(fn, http.StatusCreated)
Expand All @@ -76,7 +76,7 @@ func (ctrl *V1Controller) HandleLocationCreate() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
auth := services.NewContext(r.Context())
err := ctrl.repo.Locations.DeleteByGroup(auth, auth.GID, ID)
err := ctrl.repo.Locations.DeleteByGroup(auth, auth.GroupID, ID)
return nil, err
}

Expand All @@ -95,7 +95,7 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Locations.GetOneByGroup(auth, auth.GID, ID)
return ctrl.repo.Locations.GetOneByGroup(auth, auth.GroupID, ID)
}

return adapters.CommandID("id", fn, http.StatusOK)
Expand All @@ -115,7 +115,7 @@ func (ctrl *V1Controller) HandleLocationUpdate() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID, body repo.LocationUpdate) (repo.LocationOut, error) {
auth := services.NewContext(r.Context())
body.ID = ID
return ctrl.repo.Locations.UpdateByGroup(auth, auth.GID, ID, body)
return ctrl.repo.Locations.UpdateByGroup(auth, auth.GroupID, ID, body)
}

return adapters.ActionID("id", fn, http.StatusOK)
Expand Down
2 changes: 1 addition & 1 deletion backend/app/api/handlers/v1/v1_ctrl_maint_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID, q repo.MaintenanceLogQuery) (repo.MaintenanceLog, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.MaintEntry.GetLog(auth, auth.GID, ID, q)
return ctrl.repo.MaintEntry.GetLog(auth, auth.GroupID, ID, q)
}

return adapters.QueryID("id", fn, http.StatusOK)
Expand Down
6 changes: 3 additions & 3 deletions backend/app/api/handlers/v1/v1_ctrl_notifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (ctrl *V1Controller) HandleGetUserNotifiers() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleCreateNotifier() errchain.HandlerFunc {
fn := func(r *http.Request, in repo.NotifierCreate) (repo.NotifierOut, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Notifiers.Create(auth, auth.GID, auth.UID, in)
return ctrl.repo.Notifiers.Create(auth, auth.GroupID, auth.UserID, in)
}

return adapters.Action(fn, http.StatusCreated)
Expand All @@ -57,7 +57,7 @@ func (ctrl *V1Controller) HandleCreateNotifier() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleDeleteNotifier() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
auth := services.NewContext(r.Context())
return nil, ctrl.repo.Notifiers.Delete(auth, auth.UID, ID)
return nil, ctrl.repo.Notifiers.Delete(auth, auth.UserID, ID)
}

return adapters.CommandID("id", fn, http.StatusNoContent)
Expand All @@ -75,7 +75,7 @@ func (ctrl *V1Controller) HandleDeleteNotifier() errchain.HandlerFunc {
func (ctrl *V1Controller) HandleUpdateNotifier() errchain.HandlerFunc {
fn := func(r *http.Request, ID uuid.UUID, in repo.NotifierUpdate) (repo.NotifierOut, error) {
auth := services.NewContext(r.Context())
return ctrl.repo.Notifiers.Update(auth, auth.UID, ID, in)
return ctrl.repo.Notifiers.Update(auth, auth.UserID, ID, in)
}

return adapters.ActionID("id", fn, http.StatusOK)
Expand Down
Loading
Loading