mirror of
https://github.com/hay-kot/homebox.git
synced 2025-08-01 23:30:27 +00:00
Merge 64d2957853
into 6fd8457e5a
This commit is contained in:
commit
1b65cbdfcd
92 changed files with 13974 additions and 7677 deletions
14
.github/workflows/partial-frontend.yaml
vendored
14
.github/workflows/partial-frontend.yaml
vendored
|
@ -13,9 +13,13 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v3.0.0
|
- uses: pnpm/action-setup@v3.0.0
|
||||||
with:
|
with:
|
||||||
version: 6.0.2
|
version: 9
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --shamefully-hoist
|
run: pnpm install --shamefully-hoist
|
||||||
|
@ -46,18 +50,18 @@ jobs:
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "1.21"
|
go-version: "1.22"
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
|
|
||||||
- uses: pnpm/action-setup@v3.0.0
|
- uses: pnpm/action-setup@v3.0.0
|
||||||
with:
|
with:
|
||||||
version: 6.0.2
|
version: 9
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install --shamefully-hoist
|
||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
|
|
||||||
- name: Run Integration Tests
|
- name: Run Integration Tests
|
||||||
|
|
11
Taskfile.yml
11
Taskfile.yml
|
@ -5,6 +5,11 @@ env:
|
||||||
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_pragma=busy_timeout=1000&_pragma=journal_mode=WAL&_fk=1
|
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_pragma=busy_timeout=1000&_pragma=journal_mode=WAL&_fk=1
|
||||||
HBOX_OPTIONS_ALLOW_REGISTRATION: true
|
HBOX_OPTIONS_ALLOW_REGISTRATION: true
|
||||||
UNSAFE_DISABLE_PASSWORD_PROJECTION: "yes_i_am_sure"
|
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:
|
tasks:
|
||||||
setup:
|
setup:
|
||||||
desc: Install development dependencies
|
desc: Install development dependencies
|
||||||
|
@ -79,6 +84,12 @@ tasks:
|
||||||
cmds:
|
cmds:
|
||||||
- go mod tidy
|
- go mod tidy
|
||||||
|
|
||||||
|
go:fmt:
|
||||||
|
desc: Runs go fmt on the backend
|
||||||
|
dir: backend
|
||||||
|
cmds:
|
||||||
|
- gofumpt -w .
|
||||||
|
|
||||||
go:lint:
|
go:lint:
|
||||||
desc: Runs golangci-lint
|
desc: Runs golangci-lint
|
||||||
dir: backend
|
dir: backend
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
run:
|
run:
|
||||||
timeout: 10m
|
timeout: 10m
|
||||||
skip-dirs:
|
|
||||||
- internal/data/ent.*
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
|
errcheck:
|
||||||
|
exclude-functions:
|
||||||
|
- (net/http.ResponseWriter).Write
|
||||||
goconst:
|
goconst:
|
||||||
min-len: 5
|
min-len: 5
|
||||||
min-occurrences: 5
|
min-occurrences: 5
|
||||||
|
@ -71,4 +72,6 @@ linters:
|
||||||
- sqlclosecheck
|
- sqlclosecheck
|
||||||
issues:
|
issues:
|
||||||
exclude-use-default: false
|
exclude-use-default: false
|
||||||
fix: true
|
fix: false
|
||||||
|
exclude-dirs:
|
||||||
|
- internal/data/ent.*
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
type app struct {
|
type app struct {
|
||||||
conf *config.Config
|
conf *config.Config
|
||||||
mailer mailer.Mailer
|
mailer *mailer.Mailer
|
||||||
db *ent.Client
|
db *ent.Client
|
||||||
repos *repo.AllRepos
|
repos *repo.AllRepos
|
||||||
services *services.AllServices
|
services *services.AllServices
|
||||||
|
@ -23,7 +23,7 @@ func new(conf *config.Config) *app {
|
||||||
conf: conf,
|
conf: conf,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.mailer = mailer.Mailer{
|
s.mailer = &mailer.Mailer{
|
||||||
Host: s.conf.Mailer.Host,
|
Host: s.conf.Mailer.Host,
|
||||||
Port: s.conf.Mailer.Port,
|
Port: s.conf.Mailer.Port,
|
||||||
Username: s.conf.Mailer.Username,
|
Username: s.conf.Mailer.Username,
|
||||||
|
|
|
@ -40,20 +40,18 @@ func (a *app) SetupDemo() {
|
||||||
_, err = a.services.User.RegisterUser(ctx, registration)
|
_, err = a.services.User.RegisterUser(ctx, registration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("Failed to register demo user")
|
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)
|
token, err := a.services.User.Login(ctx, registration.Email, registration.Password, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("Failed to login demo user")
|
log.Err(err).Msg("Failed to login demo user")
|
||||||
log.Fatal().Msg("Failed to setup demo")
|
log.Fatal().Msg("Failed to setup demo")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
self, err := a.services.User.GetSelf(ctx, token.Raw)
|
self, err := a.services.User.GetSelf(ctx, token.Raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("Failed to get self")
|
log.Err(err).Msg("Failed to get self")
|
||||||
log.Fatal().Msg("Failed to setup demo")
|
log.Fatal().Msg("Failed to setup demo")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = a.services.Items.CsvImport(ctx, self.GroupID, strings.NewReader(csvText))
|
_, err = a.services.Items.CsvImport(ctx, self.GroupID, strings.NewReader(csvText))
|
||||||
|
|
|
@ -153,7 +153,7 @@ func (ctrl *V1Controller) HandleCacheWS() errchain.HandlerFunc {
|
||||||
|
|
||||||
m.HandleConnect(func(s *melody.Session) {
|
m.HandleConnect(func(s *melody.Session) {
|
||||||
auth := services.NewContext(s.Request.Context())
|
auth := services.NewContext(s.Request.Context())
|
||||||
s.Set("gid", auth.GID)
|
s.Set("gid", auth.GroupID)
|
||||||
})
|
})
|
||||||
|
|
||||||
factory := func(e string) func(data any) {
|
factory := func(e string) func(data any) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ func actionHandlerFactory(ref string, fn func(context.Context, uuid.UUID) (int,
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
ctx := services.NewContext(r.Context())
|
ctx := services.NewContext(r.Context())
|
||||||
|
|
||||||
totalCompleted, err := fn(ctx, ctx.GID)
|
totalCompleted, err := fn(ctx, ctx.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Str("action_ref", ref).Msg("failed to run action")
|
log.Err(err).Str("action_ref", ref).Msg("failed to run action")
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
|
|
|
@ -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 {
|
if err != nil {
|
||||||
log.Err(err).Msg("failed to get item")
|
log.Err(err).Msg("failed to get item")
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
|
|
|
@ -35,7 +35,7 @@ type (
|
||||||
func (ctrl *V1Controller) HandleGroupGet() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleGroupGet() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request) (repo.Group, error) {
|
fn := func(r *http.Request) (repo.Group, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Command(fn, http.StatusOK)
|
||||||
|
|
|
@ -79,7 +79,7 @@ func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
ctx := services.NewContext(r.Context())
|
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 err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{
|
return server.JSON(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{
|
||||||
|
@ -105,12 +105,12 @@ func (ctrl *V1Controller) HandleItemsGetAll() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleItemFullPath() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleItemFullPath() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) ([]repo.ItemPath, error) {
|
fn := func(r *http.Request, ID uuid.UUID) ([]repo.ItemPath, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ func (ctrl *V1Controller) HandleItemGet() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) (repo.ItemOut, error) {
|
fn := func(r *http.Request, ID uuid.UUID) (repo.ItemOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.CommandID("id", fn, http.StatusOK)
|
||||||
|
@ -183,7 +183,7 @@ func (ctrl *V1Controller) HandleItemGet() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleItemDelete() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleItemDelete() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ func (ctrl *V1Controller) HandleItemUpdate() errchain.HandlerFunc {
|
||||||
auth := services.NewContext(r.Context())
|
auth := services.NewContext(r.Context())
|
||||||
|
|
||||||
body.ID = ID
|
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)
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
|
@ -226,12 +226,12 @@ func (ctrl *V1Controller) HandleItemPatch() errchain.HandlerFunc {
|
||||||
auth := services.NewContext(r.Context())
|
auth := services.NewContext(r.Context())
|
||||||
|
|
||||||
body.ID = ID
|
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 {
|
if err != nil {
|
||||||
return repo.ItemOut{}, err
|
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)
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
|
@ -249,7 +249,7 @@ func (ctrl *V1Controller) HandleItemPatch() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleGetAllCustomFieldNames() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleGetAllCustomFieldNames() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request) ([]string, error) {
|
fn := func(r *http.Request) ([]string, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Command(fn, http.StatusOK)
|
||||||
|
@ -271,7 +271,7 @@ func (ctrl *V1Controller) HandleGetAllCustomFieldValues() errchain.HandlerFunc {
|
||||||
|
|
||||||
fn := func(r *http.Request, q query) ([]string, error) {
|
fn := func(r *http.Request, q query) ([]string, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Query(fn, http.StatusOK)
|
||||||
|
@ -323,7 +323,7 @@ func (ctrl *V1Controller) HandleItemsExport() errchain.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) error {
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
ctx := services.NewContext(r.Context())
|
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 {
|
if err != nil {
|
||||||
log.Err(err).Msg("failed to export items")
|
log.Err(err).Msg("failed to export items")
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
|
|
|
@ -168,7 +168,7 @@ func (ctrl *V1Controller) handleItemAttachmentsHandler(w http.ResponseWriter, r
|
||||||
|
|
||||||
// Delete Attachment Handler
|
// Delete Attachment Handler
|
||||||
case http.MethodDelete:
|
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 {
|
if err != nil {
|
||||||
log.Err(err).Msg("failed to delete attachment")
|
log.Err(err).Msg("failed to delete attachment")
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request) ([]repo.LabelSummary, error) {
|
fn := func(r *http.Request) ([]repo.LabelSummary, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Command(fn, http.StatusOK)
|
||||||
|
@ -39,7 +39,7 @@ func (ctrl *V1Controller) HandleLabelsGetAll() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleLabelsCreate() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLabelsCreate() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, data repo.LabelCreate) (repo.LabelOut, error) {
|
fn := func(r *http.Request, data repo.LabelCreate) (repo.LabelOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
|
@ -57,7 +57,7 @@ func (ctrl *V1Controller) HandleLabelsCreate() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleLabelDelete() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLabelDelete() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ func (ctrl *V1Controller) HandleLabelDelete() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleLabelGet() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLabelGet() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) (repo.LabelOut, error) {
|
fn := func(r *http.Request, ID uuid.UUID) (repo.LabelOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.CommandID("id", fn, http.StatusOK)
|
||||||
|
@ -95,7 +95,7 @@ func (ctrl *V1Controller) HandleLabelUpdate() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID, data repo.LabelUpdate) (repo.LabelOut, error) {
|
fn := func(r *http.Request, ID uuid.UUID, data repo.LabelUpdate) (repo.LabelOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
auth := services.NewContext(r.Context())
|
||||||
data.ID = ID
|
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)
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, query repo.TreeQuery) ([]repo.TreeItem, error) {
|
fn := func(r *http.Request, query repo.TreeQuery) ([]repo.TreeItem, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Query(fn, http.StatusOK)
|
||||||
|
@ -40,7 +40,7 @@ func (ctrl *V1Controller) HandleLocationTreeQuery() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, q repo.LocationQuery) ([]repo.LocationOutCount, error) {
|
fn := func(r *http.Request, q repo.LocationQuery) ([]repo.LocationOutCount, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Query(fn, http.StatusOK)
|
||||||
|
@ -58,7 +58,7 @@ func (ctrl *V1Controller) HandleLocationGetAll() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleLocationCreate() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLocationCreate() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, createData repo.LocationCreate) (repo.LocationOut, error) {
|
fn := func(r *http.Request, createData repo.LocationCreate) (repo.LocationOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
|
@ -76,7 +76,7 @@ func (ctrl *V1Controller) HandleLocationCreate() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ func (ctrl *V1Controller) HandleLocationDelete() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleLocationGet() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) {
|
fn := func(r *http.Request, ID uuid.UUID) (repo.LocationOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.CommandID("id", fn, http.StatusOK)
|
||||||
|
@ -115,7 +115,7 @@ func (ctrl *V1Controller) HandleLocationUpdate() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID, body repo.LocationUpdate) (repo.LocationOut, error) {
|
fn := func(r *http.Request, ID uuid.UUID, body repo.LocationUpdate) (repo.LocationOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
auth := services.NewContext(r.Context())
|
||||||
body.ID = ID
|
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)
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleMaintenanceLogGet() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID, q repo.MaintenanceLogQuery) (repo.MaintenanceLog, error) {
|
fn := func(r *http.Request, ID uuid.UUID, q repo.MaintenanceLogQuery) (repo.MaintenanceLog, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.QueryID("id", fn, http.StatusOK)
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (ctrl *V1Controller) HandleGetUserNotifiers() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleCreateNotifier() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleCreateNotifier() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, in repo.NotifierCreate) (repo.NotifierOut, error) {
|
fn := func(r *http.Request, in repo.NotifierCreate) (repo.NotifierOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.Action(fn, http.StatusCreated)
|
||||||
|
@ -57,7 +57,7 @@ func (ctrl *V1Controller) HandleCreateNotifier() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleDeleteNotifier() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleDeleteNotifier() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
fn := func(r *http.Request, ID uuid.UUID) (any, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.CommandID("id", fn, http.StatusNoContent)
|
||||||
|
@ -75,7 +75,7 @@ func (ctrl *V1Controller) HandleDeleteNotifier() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleUpdateNotifier() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleUpdateNotifier() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request, ID uuid.UUID, in repo.NotifierUpdate) (repo.NotifierOut, error) {
|
fn := func(r *http.Request, ID uuid.UUID, in repo.NotifierUpdate) (repo.NotifierOut, error) {
|
||||||
auth := services.NewContext(r.Context())
|
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)
|
return adapters.ActionID("id", fn, http.StatusOK)
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
func (ctrl *V1Controller) HandleGroupStatisticsLocations() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleGroupStatisticsLocations() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request) ([]repo.TotalsByOrganizer, error) {
|
fn := func(r *http.Request) ([]repo.TotalsByOrganizer, error) {
|
||||||
auth := services.NewContext(r.Context())
|
auth := services.NewContext(r.Context())
|
||||||
return ctrl.repo.Groups.StatsLocationsByPurchasePrice(auth, auth.GID)
|
return ctrl.repo.Groups.StatsLocationsByPurchasePrice(auth, auth.GroupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return adapters.Command(fn, http.StatusOK)
|
return adapters.Command(fn, http.StatusOK)
|
||||||
|
@ -40,7 +40,7 @@ func (ctrl *V1Controller) HandleGroupStatisticsLocations() errchain.HandlerFunc
|
||||||
func (ctrl *V1Controller) HandleGroupStatisticsLabels() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleGroupStatisticsLabels() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request) ([]repo.TotalsByOrganizer, error) {
|
fn := func(r *http.Request) ([]repo.TotalsByOrganizer, error) {
|
||||||
auth := services.NewContext(r.Context())
|
auth := services.NewContext(r.Context())
|
||||||
return ctrl.repo.Groups.StatsLabelsByPurchasePrice(auth, auth.GID)
|
return ctrl.repo.Groups.StatsLabelsByPurchasePrice(auth, auth.GroupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return adapters.Command(fn, http.StatusOK)
|
return adapters.Command(fn, http.StatusOK)
|
||||||
|
@ -57,7 +57,7 @@ func (ctrl *V1Controller) HandleGroupStatisticsLabels() errchain.HandlerFunc {
|
||||||
func (ctrl *V1Controller) HandleGroupStatistics() errchain.HandlerFunc {
|
func (ctrl *V1Controller) HandleGroupStatistics() errchain.HandlerFunc {
|
||||||
fn := func(r *http.Request) (repo.GroupStatistics, error) {
|
fn := func(r *http.Request) (repo.GroupStatistics, error) {
|
||||||
auth := services.NewContext(r.Context())
|
auth := services.NewContext(r.Context())
|
||||||
return ctrl.repo.Groups.StatsGroup(auth, auth.GID)
|
return ctrl.repo.Groups.StatsGroup(auth, auth.GroupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return adapters.Command(fn, http.StatusOK)
|
return adapters.Command(fn, http.StatusOK)
|
||||||
|
@ -94,7 +94,7 @@ func (ctrl *V1Controller) HandleGroupStatisticsPriceOverTime() errchain.HandlerF
|
||||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
return validate.NewRequestError(err, http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
stats, err := ctrl.repo.Groups.StatsPurchasePrice(ctx, ctx.GID, startDate, endDate)
|
stats, err := ctrl.repo.Groups.StatsPurchasePrice(ctx, ctx.GroupID, startDate, endDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||||
"github.com/hay-kot/httpkit/errchain"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
"github.com/hay-kot/httpkit/server"
|
"github.com/hay-kot/httpkit/server"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
@ -115,12 +117,10 @@ func (ctrl *V1Controller) HandleUserSelfDelete() errchain.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type ChangePassword struct {
|
||||||
ChangePassword struct {
|
Current string `json:"current,omitempty"`
|
||||||
Current string `json:"current,omitempty"`
|
New string `json:"new,omitempty"`
|
||||||
New string `json:"new,omitempty"`
|
}
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// HandleUserSelfChangePassword godoc
|
// HandleUserSelfChangePassword godoc
|
||||||
//
|
//
|
||||||
|
@ -144,7 +144,7 @@ func (ctrl *V1Controller) HandleUserSelfChangePassword() errchain.HandlerFunc {
|
||||||
|
|
||||||
ctx := services.NewContext(r.Context())
|
ctx := services.NewContext(r.Context())
|
||||||
|
|
||||||
ok := ctrl.svc.User.ChangePassword(ctx, cp.Current, cp.New)
|
ok := ctrl.svc.User.PasswordChange(ctx, cp.Current, cp.New)
|
||||||
if !ok {
|
if !ok {
|
||||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
@ -152,3 +152,73 @@ func (ctrl *V1Controller) HandleUserSelfChangePassword() errchain.HandlerFunc {
|
||||||
return server.JSON(w, http.StatusNoContent, nil)
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleUserSelfChangePasswordWithToken godoc
|
||||||
|
//
|
||||||
|
// @Summary Change Password
|
||||||
|
// @Tags User
|
||||||
|
// @Success 204
|
||||||
|
// @Param payload body ChangePassword true "Password Payload"
|
||||||
|
// @Router /v1/users/change-password-token [PUT]
|
||||||
|
func (ctrl *V1Controller) HandleUserSelfChangePasswordWithToken() errchain.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
tokenQueryParam := r.URL.Query().Get("token")
|
||||||
|
if tokenQueryParam == "" {
|
||||||
|
return validate.NewRequestError(fmt.Errorf("missing token query param"), http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctrl.isDemo {
|
||||||
|
return validate.NewRequestError(nil, http.StatusForbidden)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cp ChangePassword
|
||||||
|
err := server.Decode(r, &cp)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg("user failed to change password")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := services.NewContext(r.Context())
|
||||||
|
|
||||||
|
ok := ctrl.svc.User.PasswordChange(ctx, cp.Current, cp.New)
|
||||||
|
if !ok {
|
||||||
|
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleUserRequestPasswordReset godoc
|
||||||
|
//
|
||||||
|
// @Summary Request Password Reset
|
||||||
|
// @Tags User
|
||||||
|
// @Produce json
|
||||||
|
// @Param payload body services.PasswordResetRequest true "User Data"
|
||||||
|
// @Success 204
|
||||||
|
// @Router /v1/users/request-password-reset [Post]
|
||||||
|
func (ctrl *V1Controller) HandleUserRequestPasswordReset() errchain.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
if ctrl.isDemo {
|
||||||
|
return validate.NewRequestError(nil, http.StatusForbidden)
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := adapters.DecodeBody[services.PasswordResetRequest](r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
err = ctrl.svc.User.PasswordResetRequest(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().
|
||||||
|
Err(err).
|
||||||
|
Str("email", v.Email).
|
||||||
|
Msg("failed to request password reset")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return server.JSON(w, http.StatusNoContent, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -115,11 +115,11 @@ func run(cfg *config.Config) error {
|
||||||
|
|
||||||
err = c.Schema.Create(context.Background(), options...)
|
err = c.Schema.Create(context.Background(), options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().
|
log.Fatal(). // nolint
|
||||||
Err(err).
|
Err(err).
|
||||||
Str("driver", "sqlite").
|
Str("driver", "sqlite").
|
||||||
Str("url", cfg.Storage.SqliteURL).
|
Str("url", cfg.Storage.SqliteURL).
|
||||||
Msg("failed creating schema resources")
|
Msg("failed creating schema resources")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.RemoveAll(temp)
|
err = os.RemoveAll(temp)
|
||||||
|
@ -160,6 +160,8 @@ func run(cfg *config.Config) error {
|
||||||
app.repos = repo.New(c, app.bus, cfg.Storage.Data)
|
app.repos = repo.New(c, app.bus, cfg.Storage.Data)
|
||||||
app.services = services.New(
|
app.services = services.New(
|
||||||
app.repos,
|
app.repos,
|
||||||
|
app.conf.BaseURL,
|
||||||
|
app.mailer,
|
||||||
services.WithAutoIncrementAssetID(cfg.Options.AutoIncrementAssetID),
|
services.WithAutoIncrementAssetID(cfg.Options.AutoIncrementAssetID),
|
||||||
services.WithCurrencies(currencies),
|
services.WithCurrencies(currencies),
|
||||||
)
|
)
|
||||||
|
@ -180,7 +182,7 @@ func run(cfg *config.Config) error {
|
||||||
|
|
||||||
chain := errchain.New(mid.Errors(logger))
|
chain := errchain.New(mid.Errors(logger))
|
||||||
|
|
||||||
app.mountRoutes(router, chain, app.repos)
|
app.mountRoutes(router, chain)
|
||||||
|
|
||||||
runner := graceful.NewRunner()
|
runner := graceful.NewRunner()
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/app/api/providers"
|
"github.com/hay-kot/homebox/backend/app/api/providers"
|
||||||
_ "github.com/hay-kot/homebox/backend/app/api/static/docs"
|
_ "github.com/hay-kot/homebox/backend/app/api/static/docs"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
|
||||||
"github.com/hay-kot/httpkit/errchain"
|
"github.com/hay-kot/httpkit/errchain"
|
||||||
httpSwagger "github.com/swaggo/http-swagger/v2" // http-swagger middleware
|
httpSwagger "github.com/swaggo/http-swagger/v2" // http-swagger middleware
|
||||||
)
|
)
|
||||||
|
@ -37,7 +36,7 @@ func (a *app) debugRouter() *http.ServeMux {
|
||||||
}
|
}
|
||||||
|
|
||||||
// registerRoutes registers all the routes for the API
|
// registerRoutes registers all the routes for the API
|
||||||
func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllRepos) {
|
func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain) {
|
||||||
registerMimes()
|
registerMimes()
|
||||||
|
|
||||||
r.Get("/swagger/*", httpSwagger.Handler(
|
r.Get("/swagger/*", httpSwagger.Handler(
|
||||||
|
@ -72,6 +71,7 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
|
||||||
|
|
||||||
r.Post(v1Base("/users/register"), chain.ToHandlerFunc(v1Ctrl.HandleUserRegistration()))
|
r.Post(v1Base("/users/register"), chain.ToHandlerFunc(v1Ctrl.HandleUserRegistration()))
|
||||||
r.Post(v1Base("/users/login"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogin(providers...)))
|
r.Post(v1Base("/users/login"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogin(providers...)))
|
||||||
|
r.Post(v1Base("/users/request-password-reset"), chain.ToHandlerFunc(v1Ctrl.HandleUserRequestPasswordReset()))
|
||||||
|
|
||||||
userMW := []errchain.Middleware{
|
userMW := []errchain.Middleware{
|
||||||
a.mwAuthToken,
|
a.mwAuthToken,
|
||||||
|
@ -85,6 +85,7 @@ func (a *app) mountRoutes(r *chi.Mux, chain *errchain.ErrChain, repos *repo.AllR
|
||||||
r.Post(v1Base("/users/logout"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogout(), userMW...))
|
r.Post(v1Base("/users/logout"), chain.ToHandlerFunc(v1Ctrl.HandleAuthLogout(), userMW...))
|
||||||
r.Get(v1Base("/users/refresh"), chain.ToHandlerFunc(v1Ctrl.HandleAuthRefresh(), userMW...))
|
r.Get(v1Base("/users/refresh"), chain.ToHandlerFunc(v1Ctrl.HandleAuthRefresh(), userMW...))
|
||||||
r.Put(v1Base("/users/self/change-password"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfChangePassword(), userMW...))
|
r.Put(v1Base("/users/self/change-password"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfChangePassword(), userMW...))
|
||||||
|
r.Put(v1Base("/users/self/change-password-token"), chain.ToHandlerFunc(v1Ctrl.HandleUserSelfChangePasswordWithToken()))
|
||||||
|
|
||||||
r.Post(v1Base("/groups/invitations"), chain.ToHandlerFunc(v1Ctrl.HandleGroupInvitationsCreate(), userMW...))
|
r.Post(v1Base("/groups/invitations"), chain.ToHandlerFunc(v1Ctrl.HandleGroupInvitationsCreate(), userMW...))
|
||||||
r.Get(v1Base("/groups/statistics"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatistics(), userMW...))
|
r.Get(v1Base("/groups/statistics"), chain.ToHandlerFunc(v1Ctrl.HandleGroupStatistics(), userMW...))
|
||||||
|
|
|
@ -1792,6 +1792,33 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/users/request-password-reset": {
|
||||||
|
"post": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"User"
|
||||||
|
],
|
||||||
|
"summary": "Request Password Reset",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "User Data",
|
||||||
|
"name": "payload",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/services.PasswordResetRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/users/self": {
|
"/v1/users/self": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -2825,6 +2852,14 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"services.PasswordResetRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"services.UserRegistration": {
|
"services.UserRegistration": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -1785,6 +1785,33 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/users/request-password-reset": {
|
||||||
|
"post": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"User"
|
||||||
|
],
|
||||||
|
"summary": "Request Password Reset",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "User Data",
|
||||||
|
"name": "payload",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/services.PasswordResetRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/users/self": {
|
"/v1/users/self": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -2818,6 +2845,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"services.PasswordResetRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"services.UserRegistration": {
|
"services.UserRegistration": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -620,6 +620,11 @@ definitions:
|
||||||
value:
|
value:
|
||||||
type: number
|
type: number
|
||||||
type: object
|
type: object
|
||||||
|
services.PasswordResetRequest:
|
||||||
|
properties:
|
||||||
|
email:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
services.UserRegistration:
|
services.UserRegistration:
|
||||||
properties:
|
properties:
|
||||||
email:
|
email:
|
||||||
|
@ -1817,6 +1822,23 @@ paths:
|
||||||
summary: Register New User
|
summary: Register New User
|
||||||
tags:
|
tags:
|
||||||
- User
|
- User
|
||||||
|
/v1/users/request-password-reset:
|
||||||
|
post:
|
||||||
|
parameters:
|
||||||
|
- description: User Data
|
||||||
|
in: body
|
||||||
|
name: payload
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/services.PasswordResetRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: No Content
|
||||||
|
summary: Request Password Reset
|
||||||
|
tags:
|
||||||
|
- User
|
||||||
/v1/users/self:
|
/v1/users/self:
|
||||||
delete:
|
delete:
|
||||||
produces:
|
produces:
|
||||||
|
|
|
@ -71,7 +71,7 @@ func main() {
|
||||||
text = replace.Regex.ReplaceAllString(text, replace.Text)
|
text = replace.Regex.ReplaceAllString(text, replace.Text)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile(path, []byte(text), 0644)
|
err = os.WriteFile(path, []byte(text), 0o644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
@ -14,6 +14,7 @@ require (
|
||||||
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a
|
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/schema v1.2.1
|
github.com/gorilla/schema v1.2.1
|
||||||
|
github.com/hay-kot/easyemails v0.0.0-20240206011027-25232fb79aa3
|
||||||
github.com/hay-kot/httpkit v0.0.9
|
github.com/hay-kot/httpkit v0.0.9
|
||||||
github.com/mattn/go-sqlite3 v1.14.22
|
github.com/mattn/go-sqlite3 v1.14.22
|
||||||
github.com/olahol/melody v1.1.4
|
github.com/olahol/melody v1.1.4
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
ariga.io/atlas v0.19.0 h1:gilVpXabeiGhGI9lj/rQURkXBemnloc41RGOtwVLNc4=
|
|
||||||
ariga.io/atlas v0.19.0/go.mod h1:uj3pm+hUTVN/X5yfdBexHlZv+1Xu5u5ZbZx7+CDavNU=
|
|
||||||
ariga.io/atlas v0.19.1 h1:QzBHkakwzEhmPWOzNhw8Yr/Bbicj6Iq5hwEoNI/Jr9A=
|
ariga.io/atlas v0.19.1 h1:QzBHkakwzEhmPWOzNhw8Yr/Bbicj6Iq5hwEoNI/Jr9A=
|
||||||
ariga.io/atlas v0.19.1/go.mod h1:VPlcXdd4w2KqKnH54yEZcry79UAhpaWaxEsmn5JRNoE=
|
ariga.io/atlas v0.19.1/go.mod h1:VPlcXdd4w2KqKnH54yEZcry79UAhpaWaxEsmn5JRNoE=
|
||||||
entgo.io/ent v0.12.5 h1:KREM5E4CSoej4zeGa88Ou/gfturAnpUv0mzAjch1sj4=
|
entgo.io/ent v0.12.5 h1:KREM5E4CSoej4zeGa88Ou/gfturAnpUv0mzAjch1sj4=
|
||||||
|
@ -14,6 +12,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
|
||||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||||
github.com/ardanlabs/conf/v3 v3.1.7 h1:p232cF68TafoA5U9ZlbxUIhGJtGNdKHBXF80Fdqb5t0=
|
github.com/ardanlabs/conf/v3 v3.1.7 h1:p232cF68TafoA5U9ZlbxUIhGJtGNdKHBXF80Fdqb5t0=
|
||||||
github.com/ardanlabs/conf/v3 v3.1.7/go.mod h1:zclexWKe0NVj6LHQ8NgDDZ7bQ1spE0KeKPFficdtAjU=
|
github.com/ardanlabs/conf/v3 v3.1.7/go.mod h1:zclexWKe0NVj6LHQ8NgDDZ7bQ1spE0KeKPFficdtAjU=
|
||||||
|
github.com/bradleyjkemp/cupaloy v2.3.0+incompatible h1:UafIjBvWQmS9i/xRg+CamMrnLTKNzo+bdmT/oH34c2Y=
|
||||||
|
github.com/bradleyjkemp/cupaloy v2.3.0+incompatible/go.mod h1:Au1Xw1sgaJ5iSFktEhYsS0dbQiS1B0/XMXl+42y9Ilk=
|
||||||
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
|
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
|
||||||
github.com/containrrr/shoutrrr v0.8.0/go.mod h1:ioyQAyu1LJY6sILuNyKaQaw+9Ttik5QePU8atnAdO2o=
|
github.com/containrrr/shoutrrr v0.8.0/go.mod h1:ioyQAyu1LJY6sILuNyKaQaw+9Ttik5QePU8atnAdO2o=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
|
@ -84,12 +84,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs
|
||||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||||
github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI=
|
github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI=
|
||||||
github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
|
github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
|
||||||
github.com/hay-kot/httpkit v0.0.6 h1:BidC4UrkS7zRhoTdpKLeF8ODJPKcOZkJ2tk2t2ZIQjQ=
|
github.com/hay-kot/easyemails v0.0.0-20240206011027-25232fb79aa3 h1:EljujAOvukSS+sh8e883j4vhEiYG4EvJFAhl+XvUYe8=
|
||||||
github.com/hay-kot/httpkit v0.0.6/go.mod h1:1s/OJwWRyH6tBtTw76jTp6kwBYvjswziXaokPQH7eKQ=
|
github.com/hay-kot/easyemails v0.0.0-20240206011027-25232fb79aa3/go.mod h1:SZdhYMO2ZmEuTTDE7pHn0WanXhwteniOCYsQ3B5IT/o=
|
||||||
github.com/hay-kot/httpkit v0.0.7 h1:KxGi+MwXFavfFUfJEMpye5cnMef9TlFu3v7UZipUB8U=
|
|
||||||
github.com/hay-kot/httpkit v0.0.7/go.mod h1:AD22YluZrvBDxmtB3Pw2SOyp3A2PZqcmBZa0+COrhoU=
|
|
||||||
github.com/hay-kot/httpkit v0.0.8 h1:n+Z5z35YZcdD9cGwbnIPRbrgDw9LY6lqakH4zYr5z+A=
|
|
||||||
github.com/hay-kot/httpkit v0.0.8/go.mod h1:AD22YluZrvBDxmtB3Pw2SOyp3A2PZqcmBZa0+COrhoU=
|
|
||||||
github.com/hay-kot/httpkit v0.0.9 h1:hu2TPY9awmIYWXxWGubaXl2U61pPvaVsm9YwboBRGu0=
|
github.com/hay-kot/httpkit v0.0.9 h1:hu2TPY9awmIYWXxWGubaXl2U61pPvaVsm9YwboBRGu0=
|
||||||
github.com/hay-kot/httpkit v0.0.9/go.mod h1:AD22YluZrvBDxmtB3Pw2SOyp3A2PZqcmBZa0+COrhoU=
|
github.com/hay-kot/httpkit v0.0.9/go.mod h1:AD22YluZrvBDxmtB3Pw2SOyp3A2PZqcmBZa0+COrhoU=
|
||||||
github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
|
github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
|
||||||
|
@ -173,8 +169,6 @@ golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
|
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
|
||||||
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
||||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
|
||||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
|
|
|
@ -4,6 +4,7 @@ package services
|
||||||
import (
|
import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/core/currencies"
|
"github.com/hay-kot/homebox/backend/internal/core/currencies"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
|
"github.com/hay-kot/homebox/backend/pkgs/mailer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AllServices struct {
|
type AllServices struct {
|
||||||
|
@ -33,7 +34,7 @@ func WithCurrencies(v []currencies.Currency) func(*options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(repos *repo.AllRepos, opts ...OptionsFunc) *AllServices {
|
func New(repos *repo.AllRepos, baseurl string, sender *mailer.Mailer, opts ...OptionsFunc) *AllServices {
|
||||||
if repos == nil {
|
if repos == nil {
|
||||||
panic("repos cannot be nil")
|
panic("repos cannot be nil")
|
||||||
}
|
}
|
||||||
|
@ -55,7 +56,11 @@ func New(repos *repo.AllRepos, opts ...OptionsFunc) *AllServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &AllServices{
|
return &AllServices{
|
||||||
User: &UserService{repos},
|
User: &UserService{
|
||||||
|
repos: repos,
|
||||||
|
mailer: sender,
|
||||||
|
baseurl: baseurl,
|
||||||
|
},
|
||||||
Group: &GroupService{repos},
|
Group: &GroupService{repos},
|
||||||
Items: &ItemService{
|
Items: &ItemService{
|
||||||
repo: repos,
|
repo: repos,
|
||||||
|
|
|
@ -19,11 +19,11 @@ var (
|
||||||
type Context struct {
|
type Context struct {
|
||||||
context.Context
|
context.Context
|
||||||
|
|
||||||
// UID is a unique identifier for the acting user.
|
// UserID is a unique identifier for the acting user.
|
||||||
UID uuid.UUID
|
UserID uuid.UUID
|
||||||
|
|
||||||
// GID is a unique identifier for the acting users group.
|
// GroupID is a unique identifier for the acting users group.
|
||||||
GID uuid.UUID
|
GroupID uuid.UUID
|
||||||
|
|
||||||
// User is the acting user.
|
// User is the acting user.
|
||||||
User *repo.UserOut
|
User *repo.UserOut
|
||||||
|
@ -35,8 +35,8 @@ func NewContext(ctx context.Context) Context {
|
||||||
user := UseUserCtx(ctx)
|
user := UseUserCtx(ctx)
|
||||||
return Context{
|
return Context{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
UID: user.ID,
|
UserID: user.ID,
|
||||||
GID: user.GroupID,
|
GroupID: user.GroupID,
|
||||||
User: user,
|
User: user,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/faker"
|
"github.com/hay-kot/homebox/backend/pkgs/faker"
|
||||||
|
"github.com/hay-kot/homebox/backend/pkgs/mailer"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -67,15 +68,16 @@ func TestMain(m *testing.M) {
|
||||||
currencies.CollectDefaults(),
|
currencies.CollectDefaults(),
|
||||||
)
|
)
|
||||||
|
|
||||||
tSvc = New(tRepos, WithCurrencies(defaults))
|
tSvc = New(tRepos, "", &mailer.Mailer{}, WithCurrencies(defaults))
|
||||||
defer func() { _ = client.Close() }()
|
|
||||||
|
|
||||||
bootstrap()
|
bootstrap()
|
||||||
tCtx = Context{
|
tCtx = Context{
|
||||||
Context: context.Background(),
|
Context: context.Background(),
|
||||||
GID: tGroup.ID,
|
GroupID: tGroup.ID,
|
||||||
UID: tUser.ID,
|
UserID: tUser.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(m.Run())
|
exit := m.Run()
|
||||||
|
_ = client.Close()
|
||||||
|
os.Exit(exit)
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ func (s *IOSheet) Read(data io.Reader) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadItems writes the sheet to a writer.
|
// ReadItems writes the sheet to a writer.
|
||||||
func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.UUID, repos *repo.AllRepos) error {
|
func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, groupID uuid.UUID, repos *repo.AllRepos) error {
|
||||||
s.Rows = make([]ExportTSVRow, len(items))
|
s.Rows = make([]ExportTSVRow, len(items))
|
||||||
|
|
||||||
extraHeaders := map[string]struct{}{}
|
extraHeaders := map[string]struct{}{}
|
||||||
|
@ -164,7 +164,7 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
|
||||||
// TODO: Support fetching nested locations
|
// TODO: Support fetching nested locations
|
||||||
locID := item.Location.ID
|
locID := item.Location.ID
|
||||||
|
|
||||||
locPaths, err := repos.Locations.PathForLoc(context.Background(), GID, locID)
|
locPaths, err := repos.Locations.PathForLoc(context.Background(), groupID, locID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("could not get location path")
|
log.Error().Err(err).Msg("could not get location path")
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -66,7 +66,6 @@ func (svc *BackgroundService) SendNotifiersToday(ctx context.Context) error {
|
||||||
var sendErrs []error
|
var sendErrs []error
|
||||||
for i := range urls {
|
for i := range urls {
|
||||||
err := shoutrrr.Send(urls[i], bldr.String())
|
err := shoutrrr.Send(urls[i], bldr.String())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendErrs = append(sendErrs, err)
|
sendErrs = append(sendErrs, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,13 @@ func (svc *GroupService) UpdateGroup(ctx Context, data repo.GroupUpdate) (repo.G
|
||||||
return repo.Group{}, errors.New("currency cannot be empty")
|
return repo.Group{}, errors.New("currency cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.repos.Groups.GroupUpdate(ctx.Context, ctx.GID, data)
|
return svc.repos.Groups.GroupUpdate(ctx.Context, ctx.GroupID, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *GroupService) NewInvitation(ctx Context, uses int, expiresAt time.Time) (string, error) {
|
func (svc *GroupService) NewInvitation(ctx Context, uses int, expiresAt time.Time) (string, error) {
|
||||||
token := hasher.GenerateToken()
|
token := hasher.GenerateToken()
|
||||||
|
|
||||||
_, err := svc.repos.Groups.InvitationCreate(ctx, ctx.GID, repo.GroupInvitationCreate{
|
_, err := svc.repos.Groups.InvitationCreate(ctx, ctx.GroupID, repo.GroupInvitationCreate{
|
||||||
Token: token.Hash,
|
Token: token.Hash,
|
||||||
Uses: uses,
|
Uses: uses,
|
||||||
ExpiresAt: expiresAt,
|
ExpiresAt: expiresAt,
|
||||||
|
|
|
@ -27,7 +27,7 @@ type ItemService struct {
|
||||||
|
|
||||||
func (svc *ItemService) Create(ctx Context, item repo.ItemCreate) (repo.ItemOut, error) {
|
func (svc *ItemService) Create(ctx Context, item repo.ItemCreate) (repo.ItemOut, error) {
|
||||||
if svc.autoIncrementAssetID {
|
if svc.autoIncrementAssetID {
|
||||||
highest, err := svc.repo.Items.GetHighestAssetID(ctx, ctx.GID)
|
highest, err := svc.repo.Items.GetHighestAssetID(ctx, ctx.GroupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repo.ItemOut{}, err
|
return repo.ItemOut{}, err
|
||||||
}
|
}
|
||||||
|
@ -35,16 +35,16 @@ func (svc *ItemService) Create(ctx Context, item repo.ItemCreate) (repo.ItemOut,
|
||||||
item.AssetID = highest + 1
|
item.AssetID = highest + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.repo.Items.Create(ctx, ctx.GID, item)
|
return svc.repo.Items.Create(ctx, ctx.GroupID, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ItemService) EnsureAssetID(ctx context.Context, GID uuid.UUID) (int, error) {
|
func (svc *ItemService) EnsureAssetID(ctx context.Context, groupID uuid.UUID) (int, error) {
|
||||||
items, err := svc.repo.Items.GetAllZeroAssetID(ctx, GID)
|
items, err := svc.repo.Items.GetAllZeroAssetID(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
highest, err := svc.repo.Items.GetHighestAssetID(ctx, GID)
|
highest, err := svc.repo.Items.GetHighestAssetID(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ func (svc *ItemService) EnsureAssetID(ctx context.Context, GID uuid.UUID) (int,
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
highest++
|
highest++
|
||||||
|
|
||||||
err = svc.repo.Items.SetAssetID(ctx, GID, item.ID, highest)
|
err = svc.repo.Items.SetAssetID(ctx, groupID, item.ID, highest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,8 @@ func (svc *ItemService) EnsureAssetID(ctx context.Context, GID uuid.UUID) (int,
|
||||||
return finished, nil
|
return finished, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ItemService) EnsureImportRef(ctx context.Context, GID uuid.UUID) (int, error) {
|
func (svc *ItemService) EnsureImportRef(ctx context.Context, groupID uuid.UUID) (int, error) {
|
||||||
ids, err := svc.repo.Items.GetAllZeroImportRef(ctx, GID)
|
ids, err := svc.repo.Items.GetAllZeroImportRef(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ func (svc *ItemService) EnsureImportRef(ctx context.Context, GID uuid.UUID) (int
|
||||||
for _, itemID := range ids {
|
for _, itemID := range ids {
|
||||||
ref := uuid.New().String()[0:8]
|
ref := uuid.New().String()[0:8]
|
||||||
|
|
||||||
err = svc.repo.Items.Patch(ctx, GID, itemID, repo.ItemPatch{ImportRef: &ref})
|
err = svc.repo.Items.Patch(ctx, groupID, itemID, repo.ItemPatch{ImportRef: &ref})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func serializeLocation[T ~[]string](location T) string {
|
||||||
// 1. If the item does not exist, it is created.
|
// 1. If the item does not exist, it is created.
|
||||||
// 2. If the item has a ImportRef and it exists it is skipped
|
// 2. If the item has a ImportRef and it exists it is skipped
|
||||||
// 3. Locations and Labels are created if they do not exist.
|
// 3. Locations and Labels are created if they do not exist.
|
||||||
func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Reader) (int, error) {
|
func (svc *ItemService) CsvImport(ctx context.Context, groupID uuid.UUID, data io.Reader) (int, error) {
|
||||||
sheet := reporting.IOSheet{}
|
sheet := reporting.IOSheet{}
|
||||||
|
|
||||||
err := sheet.Read(data)
|
err := sheet.Read(data)
|
||||||
|
@ -109,7 +109,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
|
|
||||||
labelMap := make(map[string]uuid.UUID)
|
labelMap := make(map[string]uuid.UUID)
|
||||||
{
|
{
|
||||||
labels, err := svc.repo.Labels.GetAll(ctx, GID)
|
labels, err := svc.repo.Labels.GetAll(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
|
|
||||||
locationMap := make(map[string]uuid.UUID)
|
locationMap := make(map[string]uuid.UUID)
|
||||||
{
|
{
|
||||||
locations, err := svc.repo.Locations.Tree(ctx, GID, repo.TreeQuery{WithItems: false})
|
locations, err := svc.repo.Locations.Tree(ctx, groupID, repo.TreeQuery{WithItems: false})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
// Asset ID Pre-Check
|
// Asset ID Pre-Check
|
||||||
highestAID := repo.AssetID(-1)
|
highestAID := repo.AssetID(-1)
|
||||||
if svc.autoIncrementAssetID {
|
if svc.autoIncrementAssetID {
|
||||||
highestAID, err = svc.repo.Items.GetHighestAssetID(ctx, GID)
|
highestAID, err = svc.repo.Items.GetHighestAssetID(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
// ========================================
|
// ========================================
|
||||||
// Preflight check for existing item
|
// Preflight check for existing item
|
||||||
if row.ImportRef != "" {
|
if row.ImportRef != "" {
|
||||||
exists, err := svc.repo.Items.CheckRef(ctx, GID, row.ImportRef)
|
exists, err := svc.repo.Items.CheckRef(ctx, groupID, row.ImportRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("error checking for existing item with ref %q: %w", row.ImportRef, err)
|
return 0, fmt.Errorf("error checking for existing item with ref %q: %w", row.ImportRef, err)
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
|
|
||||||
id, ok := labelMap[label]
|
id, ok := labelMap[label]
|
||||||
if !ok {
|
if !ok {
|
||||||
newLabel, err := svc.repo.Labels.Create(ctx, GID, repo.LabelCreate{Name: label})
|
newLabel, err := svc.repo.Labels.Create(ctx, groupID, repo.LabelCreate{Name: label})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
parentID = locationMap[parentPath]
|
parentID = locationMap[parentPath]
|
||||||
}
|
}
|
||||||
|
|
||||||
newLocation, err := svc.repo.Locations.Create(ctx, GID, repo.LocationCreate{
|
newLocation, err := svc.repo.Locations.Create(ctx, groupID, repo.LocationCreate{
|
||||||
ParentID: parentID,
|
ParentID: parentID,
|
||||||
Name: pathElement,
|
Name: pathElement,
|
||||||
})
|
})
|
||||||
|
@ -261,12 +261,12 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
LabelIDs: labelIds,
|
LabelIDs: labelIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
item, err = svc.repo.Items.Create(ctx, GID, newItem)
|
item, err = svc.repo.Items.Create(ctx, groupID, newItem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
item, err = svc.repo.Items.GetByRef(ctx, GID, row.ImportRef)
|
item, err = svc.repo.Items.GetByRef(ctx, groupID, row.ImportRef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
Fields: fields,
|
Fields: fields,
|
||||||
}
|
}
|
||||||
|
|
||||||
item, err = svc.repo.Items.UpdateByGroup(ctx, GID, updateItem)
|
item, err = svc.repo.Items.UpdateByGroup(ctx, groupID, updateItem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -329,15 +329,15 @@ func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Re
|
||||||
return finished, nil
|
return finished, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ItemService) ExportTSV(ctx context.Context, GID uuid.UUID) ([][]string, error) {
|
func (svc *ItemService) ExportTSV(ctx context.Context, groupID uuid.UUID) ([][]string, error) {
|
||||||
items, err := svc.repo.Items.GetAll(ctx, GID)
|
items, err := svc.repo.Items.GetAll(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sheet := reporting.IOSheet{}
|
sheet := reporting.IOSheet{}
|
||||||
|
|
||||||
err = sheet.ReadItems(ctx, items, GID, svc.repo)
|
err = sheet.ReadItems(ctx, items, groupID, svc.repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -345,8 +345,8 @@ func (svc *ItemService) ExportTSV(ctx context.Context, GID uuid.UUID) ([][]strin
|
||||||
return sheet.TSV()
|
return sheet.TSV()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ItemService) ExportBillOfMaterialsTSV(ctx context.Context, GID uuid.UUID) ([]byte, error) {
|
func (svc *ItemService) ExportBillOfMaterialsTSV(ctx context.Context, groupID uuid.UUID) ([]byte, error) {
|
||||||
items, err := svc.repo.Items.GetAll(ctx, GID)
|
items, err := svc.repo.Items.GetAll(ctx, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func (svc *ItemService) AttachmentUpdate(ctx Context, itemID uuid.UUID, data *re
|
||||||
return repo.ItemOut{}, err
|
return repo.ItemOut{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.repo.Items.GetOneByGroup(ctx, ctx.GID, itemID)
|
return svc.repo.Items.GetOneByGroup(ctx, ctx.GroupID, itemID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AttachmentAdd adds an attachment to an item by creating an entry in the Documents table and linking it to the Attachment
|
// AttachmentAdd adds an attachment to an item by creating an entry in the Documents table and linking it to the Attachment
|
||||||
|
@ -43,13 +43,13 @@ func (svc *ItemService) AttachmentUpdate(ctx Context, itemID uuid.UUID, data *re
|
||||||
// relative path during construction of the service.
|
// relative path during construction of the service.
|
||||||
func (svc *ItemService) AttachmentAdd(ctx Context, itemID uuid.UUID, filename string, attachmentType attachment.Type, file io.Reader) (repo.ItemOut, error) {
|
func (svc *ItemService) AttachmentAdd(ctx Context, itemID uuid.UUID, filename string, attachmentType attachment.Type, file io.Reader) (repo.ItemOut, error) {
|
||||||
// Get the Item
|
// Get the Item
|
||||||
_, err := svc.repo.Items.GetOneByGroup(ctx, ctx.GID, itemID)
|
_, err := svc.repo.Items.GetOneByGroup(ctx, ctx.GroupID, itemID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repo.ItemOut{}, err
|
return repo.ItemOut{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the document
|
// Create the document
|
||||||
doc, err := svc.repo.Docs.Create(ctx, ctx.GID, repo.DocumentCreate{Title: filename, Content: file})
|
doc, err := svc.repo.Docs.Create(ctx, ctx.GroupID, repo.DocumentCreate{Title: filename, Content: file})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("failed to create document")
|
log.Err(err).Msg("failed to create document")
|
||||||
return repo.ItemOut{}, err
|
return repo.ItemOut{}, err
|
||||||
|
@ -62,7 +62,7 @@ func (svc *ItemService) AttachmentAdd(ctx Context, itemID uuid.UUID, filename st
|
||||||
return repo.ItemOut{}, err
|
return repo.ItemOut{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.repo.Items.GetOneByGroup(ctx, ctx.GID, itemID)
|
return svc.repo.Items.GetOneByGroup(ctx, ctx.GroupID, itemID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *ItemService) AttachmentDelete(ctx context.Context, gid, itemID, attachmentID uuid.UUID) error {
|
func (svc *ItemService) AttachmentDelete(ctx context.Context, gid, itemID, attachmentID uuid.UUID) error {
|
||||||
|
|
|
@ -3,12 +3,15 @@ package services
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/easyemails"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||||
|
"github.com/hay-kot/homebox/backend/pkgs/mailer"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,8 +22,15 @@ var (
|
||||||
ErrorTokenIDMismatch = errors.New("token id mismatch")
|
ErrorTokenIDMismatch = errors.New("token id mismatch")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() { // nolint: gochecknoinits
|
||||||
|
easyemails.ImageLogoHeader = "https://raw.githubusercontent.com/hay-kot/homebox/af9aa239af66df17478f5ed9283e303daf7c6775/docs/docs/assets/img/homebox-email-banner.jpg"
|
||||||
|
easyemails.ColorPrimary = "#5D7F67"
|
||||||
|
}
|
||||||
|
|
||||||
type UserService struct {
|
type UserService struct {
|
||||||
repos *repo.AllRepos
|
repos *repo.AllRepos
|
||||||
|
mailer *mailer.Mailer
|
||||||
|
baseurl string
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -39,6 +49,9 @@ type (
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
|
PasswordResetRequest struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterUser creates a new user and group in the data with the provided data. It also bootstraps the user's group
|
// RegisterUser creates a new user and group in the data with the provided data. It also bootstraps the user's group
|
||||||
|
@ -132,13 +145,13 @@ func (svc *UserService) GetSelf(ctx context.Context, requestToken string) (repo.
|
||||||
return svc.repos.AuthTokens.GetUserFromToken(ctx, hash)
|
return svc.repos.AuthTokens.GetUserFromToken(ctx, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data repo.UserUpdate) (repo.UserOut, error) {
|
func (svc *UserService) UpdateSelf(ctx context.Context, userID uuid.UUID, data repo.UserUpdate) (repo.UserOut, error) {
|
||||||
err := svc.repos.Users.Update(ctx, ID, data)
|
err := svc.repos.Users.Update(ctx, userID, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repo.UserOut{}, err
|
return repo.UserOut{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return svc.repos.Users.GetOneID(ctx, ID)
|
return svc.repos.Users.GetOneID(ctx, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
@ -217,28 +230,28 @@ func (svc *UserService) RenewToken(ctx context.Context, token string) (UserAuthT
|
||||||
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
||||||
// There is _NO_ protection against deleting the wrong user, as such this should only
|
// There is _NO_ protection against deleting the wrong user, as such this should only
|
||||||
// be used when the identify of the user has been confirmed.
|
// be used when the identify of the user has been confirmed.
|
||||||
func (svc *UserService) DeleteSelf(ctx context.Context, ID uuid.UUID) error {
|
func (svc *UserService) DeleteSelf(ctx context.Context, userID uuid.UUID) error {
|
||||||
return svc.repos.Users.Delete(ctx, ID)
|
return svc.repos.Users.Delete(ctx, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc *UserService) ChangePassword(ctx Context, current string, new string) (ok bool) {
|
func (svc *UserService) PasswordChange(ctx Context, currentPassword, newPassword string) (ok bool) {
|
||||||
usr, err := svc.repos.Users.GetOneID(ctx, ctx.UID)
|
usr, err := svc.repos.Users.GetOneID(ctx, ctx.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hasher.CheckPasswordHash(current, usr.PasswordHash) {
|
if !hasher.CheckPasswordHash(currentPassword, usr.PasswordHash) {
|
||||||
log.Err(errors.New("current password is incorrect")).Msg("Failed to change password")
|
log.Err(errors.New("current password is incorrect")).Msg("Failed to change password")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
hashed, err := hasher.HashPassword(new)
|
hashed, err := hasher.HashPassword(newPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("Failed to hash password")
|
log.Err(err).Msg("Failed to hash password")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
err = svc.repos.Users.ChangePassword(ctx.Context, ctx.UID, hashed)
|
err = svc.repos.Users.ChangePassword(ctx.Context, ctx.UserID, hashed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("Failed to change password")
|
log.Err(err).Msg("Failed to change password")
|
||||||
return false
|
return false
|
||||||
|
@ -246,3 +259,80 @@ func (svc *UserService) ChangePassword(ctx Context, current string, new string)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (svc *UserService) PasswordChangeWithToken(ctx Context, token, newPassword string) error {
|
||||||
|
hashed, err := hasher.HashPassword(newPassword)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenHash := hasher.HashToken(token)
|
||||||
|
|
||||||
|
resetToken, err := svc.repos.Users.PasswordResetGet(ctx.Context, tokenHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resetToken.UserID != ctx.UserID {
|
||||||
|
return ErrorTokenIDMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
err = svc.repos.Users.ChangePassword(ctx.Context, ctx.UserID, hashed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = svc.repos.Users.PasswordResetDelete(ctx.Context, tokenHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (svc *UserService) PasswordResetRequest(ctx context.Context, req PasswordResetRequest) error {
|
||||||
|
usr, err := svc.repos.Users.GetOneEmail(ctx, req.Email)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn().Err(err).Msg("failed to get user for email reset")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
token := hasher.GenerateToken()
|
||||||
|
err = svc.repos.Users.PasswordResetCreate(ctx, usr.ID, token.Hash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resetURL, err := url.JoinPath(svc.baseurl, "reset-password/")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resetURL = resetURL + "?token=" + token.Raw
|
||||||
|
|
||||||
|
bldr := easyemails.NewBuilder().Add(
|
||||||
|
easyemails.WithParagraph(
|
||||||
|
easyemails.WithText("You have requested a password reset. Please click the link below to reset your password."),
|
||||||
|
),
|
||||||
|
easyemails.WithButton("Reset Password", resetURL),
|
||||||
|
easyemails.WithParagraph(
|
||||||
|
easyemails.WithText("[Github](https://github.com/hay-kot/homebox) · [Docs](https://hay-kot.github.io/homebox/)").
|
||||||
|
Centered(),
|
||||||
|
).
|
||||||
|
FontSize(12),
|
||||||
|
)
|
||||||
|
|
||||||
|
msg := mailer.NewMessageBuilder().
|
||||||
|
SetBody(bldr.Render()).
|
||||||
|
SetSubject("Password Reset").
|
||||||
|
SetTo(usr.Name, usr.Email).
|
||||||
|
Build()
|
||||||
|
|
||||||
|
err = svc.mailer.Send(msg)
|
||||||
|
if err != nil {
|
||||||
|
log.Err(err).Msg("Failed to send password reset email")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
184
backend/internal/data/ent/actiontoken.go
Normal file
184
backend/internal/data/ent/actiontoken.go
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent"
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ActionToken is the model entity for the ActionToken schema.
|
||||||
|
type ActionToken struct {
|
||||||
|
config `json:"-"`
|
||||||
|
// ID of the ent.
|
||||||
|
ID uuid.UUID `json:"id,omitempty"`
|
||||||
|
// UserID holds the value of the "user_id" field.
|
||||||
|
UserID uuid.UUID `json:"user_id,omitempty"`
|
||||||
|
// CreatedAt holds the value of the "created_at" field.
|
||||||
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
|
// UpdatedAt holds the value of the "updated_at" field.
|
||||||
|
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||||
|
// Action holds the value of the "action" field.
|
||||||
|
Action actiontoken.Action `json:"action,omitempty"`
|
||||||
|
// Token holds the value of the "token" field.
|
||||||
|
Token []byte `json:"token,omitempty"`
|
||||||
|
// Edges holds the relations/edges for other nodes in the graph.
|
||||||
|
// The values are being populated by the ActionTokenQuery when eager-loading is set.
|
||||||
|
Edges ActionTokenEdges `json:"edges"`
|
||||||
|
selectValues sql.SelectValues
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokenEdges holds the relations/edges for other nodes in the graph.
|
||||||
|
type ActionTokenEdges struct {
|
||||||
|
// User holds the value of the user edge.
|
||||||
|
User *User `json:"user,omitempty"`
|
||||||
|
// loadedTypes holds the information for reporting if a
|
||||||
|
// type was loaded (or requested) in eager-loading or not.
|
||||||
|
loadedTypes [1]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserOrErr returns the User value or an error if the edge
|
||||||
|
// was not loaded in eager-loading, or loaded but was not found.
|
||||||
|
func (e ActionTokenEdges) UserOrErr() (*User, error) {
|
||||||
|
if e.loadedTypes[0] {
|
||||||
|
if e.User == nil {
|
||||||
|
// Edge was loaded but was not found.
|
||||||
|
return nil, &NotFoundError{label: user.Label}
|
||||||
|
}
|
||||||
|
return e.User, nil
|
||||||
|
}
|
||||||
|
return nil, &NotLoadedError{edge: "user"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scanValues returns the types for scanning values from sql.Rows.
|
||||||
|
func (*ActionToken) scanValues(columns []string) ([]any, error) {
|
||||||
|
values := make([]any, len(columns))
|
||||||
|
for i := range columns {
|
||||||
|
switch columns[i] {
|
||||||
|
case actiontoken.FieldToken:
|
||||||
|
values[i] = new([]byte)
|
||||||
|
case actiontoken.FieldAction:
|
||||||
|
values[i] = new(sql.NullString)
|
||||||
|
case actiontoken.FieldCreatedAt, actiontoken.FieldUpdatedAt:
|
||||||
|
values[i] = new(sql.NullTime)
|
||||||
|
case actiontoken.FieldID, actiontoken.FieldUserID:
|
||||||
|
values[i] = new(uuid.UUID)
|
||||||
|
default:
|
||||||
|
values[i] = new(sql.UnknownType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||||
|
// to the ActionToken fields.
|
||||||
|
func (at *ActionToken) assignValues(columns []string, values []any) error {
|
||||||
|
if m, n := len(values), len(columns); m < n {
|
||||||
|
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
|
||||||
|
}
|
||||||
|
for i := range columns {
|
||||||
|
switch columns[i] {
|
||||||
|
case actiontoken.FieldID:
|
||||||
|
if value, ok := values[i].(*uuid.UUID); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field id", values[i])
|
||||||
|
} else if value != nil {
|
||||||
|
at.ID = *value
|
||||||
|
}
|
||||||
|
case actiontoken.FieldUserID:
|
||||||
|
if value, ok := values[i].(*uuid.UUID); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field user_id", values[i])
|
||||||
|
} else if value != nil {
|
||||||
|
at.UserID = *value
|
||||||
|
}
|
||||||
|
case actiontoken.FieldCreatedAt:
|
||||||
|
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field created_at", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
at.CreatedAt = value.Time
|
||||||
|
}
|
||||||
|
case actiontoken.FieldUpdatedAt:
|
||||||
|
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
at.UpdatedAt = value.Time
|
||||||
|
}
|
||||||
|
case actiontoken.FieldAction:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field action", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
at.Action = actiontoken.Action(value.String)
|
||||||
|
}
|
||||||
|
case actiontoken.FieldToken:
|
||||||
|
if value, ok := values[i].(*[]byte); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field token", values[i])
|
||||||
|
} else if value != nil {
|
||||||
|
at.Token = *value
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
at.selectValues.Set(columns[i], values[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the ent.Value that was dynamically selected and assigned to the ActionToken.
|
||||||
|
// This includes values selected through modifiers, order, etc.
|
||||||
|
func (at *ActionToken) Value(name string) (ent.Value, error) {
|
||||||
|
return at.selectValues.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryUser queries the "user" edge of the ActionToken entity.
|
||||||
|
func (at *ActionToken) QueryUser() *UserQuery {
|
||||||
|
return NewActionTokenClient(at.config).QueryUser(at)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update returns a builder for updating this ActionToken.
|
||||||
|
// Note that you need to call ActionToken.Unwrap() before calling this method if this ActionToken
|
||||||
|
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||||
|
func (at *ActionToken) Update() *ActionTokenUpdateOne {
|
||||||
|
return NewActionTokenClient(at.config).UpdateOne(at)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap unwraps the ActionToken entity that was returned from a transaction after it was closed,
|
||||||
|
// so that all future queries will be executed through the driver which created the transaction.
|
||||||
|
func (at *ActionToken) Unwrap() *ActionToken {
|
||||||
|
_tx, ok := at.config.driver.(*txDriver)
|
||||||
|
if !ok {
|
||||||
|
panic("ent: ActionToken is not a transactional entity")
|
||||||
|
}
|
||||||
|
at.config.driver = _tx.drv
|
||||||
|
return at
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements the fmt.Stringer.
|
||||||
|
func (at *ActionToken) String() string {
|
||||||
|
var builder strings.Builder
|
||||||
|
builder.WriteString("ActionToken(")
|
||||||
|
builder.WriteString(fmt.Sprintf("id=%v, ", at.ID))
|
||||||
|
builder.WriteString("user_id=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", at.UserID))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("created_at=")
|
||||||
|
builder.WriteString(at.CreatedAt.Format(time.ANSIC))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("updated_at=")
|
||||||
|
builder.WriteString(at.UpdatedAt.Format(time.ANSIC))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("action=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", at.Action))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("token=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", at.Token))
|
||||||
|
builder.WriteByte(')')
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokens is a parsable slice of ActionToken.
|
||||||
|
type ActionTokens []*ActionToken
|
138
backend/internal/data/ent/actiontoken/actiontoken.go
Normal file
138
backend/internal/data/ent/actiontoken/actiontoken.go
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package actiontoken
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Label holds the string label denoting the actiontoken type in the database.
|
||||||
|
Label = "action_token"
|
||||||
|
// FieldID holds the string denoting the id field in the database.
|
||||||
|
FieldID = "id"
|
||||||
|
// FieldUserID holds the string denoting the user_id field in the database.
|
||||||
|
FieldUserID = "user_id"
|
||||||
|
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||||
|
FieldCreatedAt = "created_at"
|
||||||
|
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
|
||||||
|
FieldUpdatedAt = "updated_at"
|
||||||
|
// FieldAction holds the string denoting the action field in the database.
|
||||||
|
FieldAction = "action"
|
||||||
|
// FieldToken holds the string denoting the token field in the database.
|
||||||
|
FieldToken = "token"
|
||||||
|
// EdgeUser holds the string denoting the user edge name in mutations.
|
||||||
|
EdgeUser = "user"
|
||||||
|
// Table holds the table name of the actiontoken in the database.
|
||||||
|
Table = "action_tokens"
|
||||||
|
// UserTable is the table that holds the user relation/edge.
|
||||||
|
UserTable = "action_tokens"
|
||||||
|
// UserInverseTable is the table name for the User entity.
|
||||||
|
// It exists in this package in order to avoid circular dependency with the "user" package.
|
||||||
|
UserInverseTable = "users"
|
||||||
|
// UserColumn is the table column denoting the user relation/edge.
|
||||||
|
UserColumn = "user_id"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Columns holds all SQL columns for actiontoken fields.
|
||||||
|
var Columns = []string{
|
||||||
|
FieldID,
|
||||||
|
FieldUserID,
|
||||||
|
FieldCreatedAt,
|
||||||
|
FieldUpdatedAt,
|
||||||
|
FieldAction,
|
||||||
|
FieldToken,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||||
|
func ValidColumn(column string) bool {
|
||||||
|
for i := range Columns {
|
||||||
|
if column == Columns[i] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||||
|
DefaultCreatedAt func() time.Time
|
||||||
|
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||||
|
DefaultUpdatedAt func() time.Time
|
||||||
|
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||||
|
UpdateDefaultUpdatedAt func() time.Time
|
||||||
|
// DefaultID holds the default value on creation for the "id" field.
|
||||||
|
DefaultID func() uuid.UUID
|
||||||
|
)
|
||||||
|
|
||||||
|
// Action defines the type for the "action" enum field.
|
||||||
|
type Action string
|
||||||
|
|
||||||
|
// ActionResetPassword is the default value of the Action enum.
|
||||||
|
const DefaultAction = ActionResetPassword
|
||||||
|
|
||||||
|
// Action values.
|
||||||
|
const (
|
||||||
|
ActionResetPassword Action = "reset_password"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a Action) String() string {
|
||||||
|
return string(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionValidator is a validator for the "action" field enum values. It is called by the builders before save.
|
||||||
|
func ActionValidator(a Action) error {
|
||||||
|
switch a {
|
||||||
|
case ActionResetPassword:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("actiontoken: invalid enum value for action field: %q", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrderOption defines the ordering options for the ActionToken queries.
|
||||||
|
type OrderOption func(*sql.Selector)
|
||||||
|
|
||||||
|
// ByID orders the results by the id field.
|
||||||
|
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUserID orders the results by the user_id field.
|
||||||
|
func ByUserID(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUserID, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUpdatedAt orders the results by the updated_at field.
|
||||||
|
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByAction orders the results by the action field.
|
||||||
|
func ByAction(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldAction, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByUserField orders the results by user field.
|
||||||
|
func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func newUserStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(UserInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||||
|
)
|
||||||
|
}
|
275
backend/internal/data/ent/actiontoken/where.go
Normal file
275
backend/internal/data/ent/actiontoken/where.go
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package actiontoken
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ID filters vertices based on their ID field.
|
||||||
|
func ID(id uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDEQ applies the EQ predicate on the ID field.
|
||||||
|
func IDEQ(id uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDNEQ applies the NEQ predicate on the ID field.
|
||||||
|
func IDNEQ(id uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNEQ(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDIn applies the In predicate on the ID field.
|
||||||
|
func IDIn(ids ...uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldIn(FieldID, ids...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDNotIn applies the NotIn predicate on the ID field.
|
||||||
|
func IDNotIn(ids ...uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNotIn(FieldID, ids...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDGT applies the GT predicate on the ID field.
|
||||||
|
func IDGT(id uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGT(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDGTE applies the GTE predicate on the ID field.
|
||||||
|
func IDGTE(id uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGTE(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDLT applies the LT predicate on the ID field.
|
||||||
|
func IDLT(id uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLT(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDLTE applies the LTE predicate on the ID field.
|
||||||
|
func IDLTE(id uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLTE(FieldID, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ.
|
||||||
|
func UserID(v uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldUserID, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||||
|
func CreatedAt(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||||
|
func UpdatedAt(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token applies equality check predicate on the "token" field. It's identical to TokenEQ.
|
||||||
|
func Token(v []byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldToken, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserIDEQ applies the EQ predicate on the "user_id" field.
|
||||||
|
func UserIDEQ(v uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldUserID, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserIDNEQ applies the NEQ predicate on the "user_id" field.
|
||||||
|
func UserIDNEQ(v uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNEQ(FieldUserID, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserIDIn applies the In predicate on the "user_id" field.
|
||||||
|
func UserIDIn(vs ...uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldIn(FieldUserID, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserIDNotIn applies the NotIn predicate on the "user_id" field.
|
||||||
|
func UserIDNotIn(vs ...uuid.UUID) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNotIn(FieldUserID, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||||
|
func CreatedAtEQ(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||||
|
func CreatedAtNEQ(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNEQ(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||||
|
func CreatedAtIn(vs ...time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldIn(FieldCreatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||||
|
func CreatedAtNotIn(vs ...time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||||
|
func CreatedAtGT(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGT(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||||
|
func CreatedAtGTE(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGTE(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||||
|
func CreatedAtLT(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLT(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||||
|
func CreatedAtLTE(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLTE(FieldCreatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtEQ(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtNEQ(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtIn(vs ...time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtNotIn(vs ...time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtGT(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGT(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtGTE(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGTE(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtLT(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLT(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||||
|
func UpdatedAtLTE(v time.Time) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLTE(FieldUpdatedAt, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionEQ applies the EQ predicate on the "action" field.
|
||||||
|
func ActionEQ(v Action) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldAction, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionNEQ applies the NEQ predicate on the "action" field.
|
||||||
|
func ActionNEQ(v Action) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNEQ(FieldAction, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionIn applies the In predicate on the "action" field.
|
||||||
|
func ActionIn(vs ...Action) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldIn(FieldAction, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionNotIn applies the NotIn predicate on the "action" field.
|
||||||
|
func ActionNotIn(vs ...Action) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNotIn(FieldAction, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenEQ applies the EQ predicate on the "token" field.
|
||||||
|
func TokenEQ(v []byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldEQ(FieldToken, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenNEQ applies the NEQ predicate on the "token" field.
|
||||||
|
func TokenNEQ(v []byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNEQ(FieldToken, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenIn applies the In predicate on the "token" field.
|
||||||
|
func TokenIn(vs ...[]byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldIn(FieldToken, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenNotIn applies the NotIn predicate on the "token" field.
|
||||||
|
func TokenNotIn(vs ...[]byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldNotIn(FieldToken, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenGT applies the GT predicate on the "token" field.
|
||||||
|
func TokenGT(v []byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGT(FieldToken, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenGTE applies the GTE predicate on the "token" field.
|
||||||
|
func TokenGTE(v []byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldGTE(FieldToken, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenLT applies the LT predicate on the "token" field.
|
||||||
|
func TokenLT(v []byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLT(FieldToken, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenLTE applies the LTE predicate on the "token" field.
|
||||||
|
func TokenLTE(v []byte) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.FieldLTE(FieldToken, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasUser applies the HasEdge predicate on the "user" edge.
|
||||||
|
func HasUser() predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(func(s *sql.Selector) {
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||||
|
)
|
||||||
|
sqlgraph.HasNeighbors(s, step)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates).
|
||||||
|
func HasUserWith(preds ...predicate.User) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(func(s *sql.Selector) {
|
||||||
|
step := newUserStep()
|
||||||
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
|
for _, p := range preds {
|
||||||
|
p(s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// And groups predicates with the AND operator between them.
|
||||||
|
func And(predicates ...predicate.ActionToken) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.AndPredicates(predicates...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Or groups predicates with the OR operator between them.
|
||||||
|
func Or(predicates ...predicate.ActionToken) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.OrPredicates(predicates...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not applies the not operator on the given predicate.
|
||||||
|
func Not(p predicate.ActionToken) predicate.ActionToken {
|
||||||
|
return predicate.ActionToken(sql.NotPredicates(p))
|
||||||
|
}
|
329
backend/internal/data/ent/actiontoken_create.go
Normal file
329
backend/internal/data/ent/actiontoken_create.go
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ActionTokenCreate is the builder for creating a ActionToken entity.
|
||||||
|
type ActionTokenCreate struct {
|
||||||
|
config
|
||||||
|
mutation *ActionTokenMutation
|
||||||
|
hooks []Hook
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserID sets the "user_id" field.
|
||||||
|
func (atc *ActionTokenCreate) SetUserID(u uuid.UUID) *ActionTokenCreate {
|
||||||
|
atc.mutation.SetUserID(u)
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCreatedAt sets the "created_at" field.
|
||||||
|
func (atc *ActionTokenCreate) SetCreatedAt(t time.Time) *ActionTokenCreate {
|
||||||
|
atc.mutation.SetCreatedAt(t)
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||||
|
func (atc *ActionTokenCreate) SetNillableCreatedAt(t *time.Time) *ActionTokenCreate {
|
||||||
|
if t != nil {
|
||||||
|
atc.SetCreatedAt(*t)
|
||||||
|
}
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUpdatedAt sets the "updated_at" field.
|
||||||
|
func (atc *ActionTokenCreate) SetUpdatedAt(t time.Time) *ActionTokenCreate {
|
||||||
|
atc.mutation.SetUpdatedAt(t)
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
|
||||||
|
func (atc *ActionTokenCreate) SetNillableUpdatedAt(t *time.Time) *ActionTokenCreate {
|
||||||
|
if t != nil {
|
||||||
|
atc.SetUpdatedAt(*t)
|
||||||
|
}
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAction sets the "action" field.
|
||||||
|
func (atc *ActionTokenCreate) SetAction(a actiontoken.Action) *ActionTokenCreate {
|
||||||
|
atc.mutation.SetAction(a)
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableAction sets the "action" field if the given value is not nil.
|
||||||
|
func (atc *ActionTokenCreate) SetNillableAction(a *actiontoken.Action) *ActionTokenCreate {
|
||||||
|
if a != nil {
|
||||||
|
atc.SetAction(*a)
|
||||||
|
}
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToken sets the "token" field.
|
||||||
|
func (atc *ActionTokenCreate) SetToken(b []byte) *ActionTokenCreate {
|
||||||
|
atc.mutation.SetToken(b)
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetID sets the "id" field.
|
||||||
|
func (atc *ActionTokenCreate) SetID(u uuid.UUID) *ActionTokenCreate {
|
||||||
|
atc.mutation.SetID(u)
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableID sets the "id" field if the given value is not nil.
|
||||||
|
func (atc *ActionTokenCreate) SetNillableID(u *uuid.UUID) *ActionTokenCreate {
|
||||||
|
if u != nil {
|
||||||
|
atc.SetID(*u)
|
||||||
|
}
|
||||||
|
return atc
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUser sets the "user" edge to the User entity.
|
||||||
|
func (atc *ActionTokenCreate) SetUser(u *User) *ActionTokenCreate {
|
||||||
|
return atc.SetUserID(u.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutation returns the ActionTokenMutation object of the builder.
|
||||||
|
func (atc *ActionTokenCreate) Mutation() *ActionTokenMutation {
|
||||||
|
return atc.mutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save creates the ActionToken in the database.
|
||||||
|
func (atc *ActionTokenCreate) Save(ctx context.Context) (*ActionToken, error) {
|
||||||
|
atc.defaults()
|
||||||
|
return withHooks(ctx, atc.sqlSave, atc.mutation, atc.hooks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveX calls Save and panics if Save returns an error.
|
||||||
|
func (atc *ActionTokenCreate) SaveX(ctx context.Context) *ActionToken {
|
||||||
|
v, err := atc.Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the query.
|
||||||
|
func (atc *ActionTokenCreate) Exec(ctx context.Context) error {
|
||||||
|
_, err := atc.Save(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (atc *ActionTokenCreate) ExecX(ctx context.Context) {
|
||||||
|
if err := atc.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaults sets the default values of the builder before save.
|
||||||
|
func (atc *ActionTokenCreate) defaults() {
|
||||||
|
if _, ok := atc.mutation.CreatedAt(); !ok {
|
||||||
|
v := actiontoken.DefaultCreatedAt()
|
||||||
|
atc.mutation.SetCreatedAt(v)
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.UpdatedAt(); !ok {
|
||||||
|
v := actiontoken.DefaultUpdatedAt()
|
||||||
|
atc.mutation.SetUpdatedAt(v)
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.Action(); !ok {
|
||||||
|
v := actiontoken.DefaultAction
|
||||||
|
atc.mutation.SetAction(v)
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.ID(); !ok {
|
||||||
|
v := actiontoken.DefaultID()
|
||||||
|
atc.mutation.SetID(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check runs all checks and user-defined validators on the builder.
|
||||||
|
func (atc *ActionTokenCreate) check() error {
|
||||||
|
if _, ok := atc.mutation.UserID(); !ok {
|
||||||
|
return &ValidationError{Name: "user_id", err: errors.New(`ent: missing required field "ActionToken.user_id"`)}
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.CreatedAt(); !ok {
|
||||||
|
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "ActionToken.created_at"`)}
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.UpdatedAt(); !ok {
|
||||||
|
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "ActionToken.updated_at"`)}
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.Action(); !ok {
|
||||||
|
return &ValidationError{Name: "action", err: errors.New(`ent: missing required field "ActionToken.action"`)}
|
||||||
|
}
|
||||||
|
if v, ok := atc.mutation.Action(); ok {
|
||||||
|
if err := actiontoken.ActionValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "ActionToken.action": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.Token(); !ok {
|
||||||
|
return &ValidationError{Name: "token", err: errors.New(`ent: missing required field "ActionToken.token"`)}
|
||||||
|
}
|
||||||
|
if _, ok := atc.mutation.UserID(); !ok {
|
||||||
|
return &ValidationError{Name: "user", err: errors.New(`ent: missing required edge "ActionToken.user"`)}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atc *ActionTokenCreate) sqlSave(ctx context.Context) (*ActionToken, error) {
|
||||||
|
if err := atc.check(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_node, _spec := atc.createSpec()
|
||||||
|
if err := sqlgraph.CreateNode(ctx, atc.driver, _spec); err != nil {
|
||||||
|
if sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _spec.ID.Value != nil {
|
||||||
|
if id, ok := _spec.ID.Value.(*uuid.UUID); ok {
|
||||||
|
_node.ID = *id
|
||||||
|
} else if err := _node.ID.Scan(_spec.ID.Value); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
atc.mutation.id = &_node.ID
|
||||||
|
atc.mutation.done = true
|
||||||
|
return _node, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atc *ActionTokenCreate) createSpec() (*ActionToken, *sqlgraph.CreateSpec) {
|
||||||
|
var (
|
||||||
|
_node = &ActionToken{config: atc.config}
|
||||||
|
_spec = sqlgraph.NewCreateSpec(actiontoken.Table, sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID))
|
||||||
|
)
|
||||||
|
if id, ok := atc.mutation.ID(); ok {
|
||||||
|
_node.ID = id
|
||||||
|
_spec.ID.Value = &id
|
||||||
|
}
|
||||||
|
if value, ok := atc.mutation.CreatedAt(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldCreatedAt, field.TypeTime, value)
|
||||||
|
_node.CreatedAt = value
|
||||||
|
}
|
||||||
|
if value, ok := atc.mutation.UpdatedAt(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldUpdatedAt, field.TypeTime, value)
|
||||||
|
_node.UpdatedAt = value
|
||||||
|
}
|
||||||
|
if value, ok := atc.mutation.Action(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldAction, field.TypeEnum, value)
|
||||||
|
_node.Action = value
|
||||||
|
}
|
||||||
|
if value, ok := atc.mutation.Token(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldToken, field.TypeBytes, value)
|
||||||
|
_node.Token = value
|
||||||
|
}
|
||||||
|
if nodes := atc.mutation.UserIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.M2O,
|
||||||
|
Inverse: true,
|
||||||
|
Table: actiontoken.UserTable,
|
||||||
|
Columns: []string{actiontoken.UserColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_node.UserID = nodes[0]
|
||||||
|
_spec.Edges = append(_spec.Edges, edge)
|
||||||
|
}
|
||||||
|
return _node, _spec
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokenCreateBulk is the builder for creating many ActionToken entities in bulk.
|
||||||
|
type ActionTokenCreateBulk struct {
|
||||||
|
config
|
||||||
|
err error
|
||||||
|
builders []*ActionTokenCreate
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save creates the ActionToken entities in the database.
|
||||||
|
func (atcb *ActionTokenCreateBulk) Save(ctx context.Context) ([]*ActionToken, error) {
|
||||||
|
if atcb.err != nil {
|
||||||
|
return nil, atcb.err
|
||||||
|
}
|
||||||
|
specs := make([]*sqlgraph.CreateSpec, len(atcb.builders))
|
||||||
|
nodes := make([]*ActionToken, len(atcb.builders))
|
||||||
|
mutators := make([]Mutator, len(atcb.builders))
|
||||||
|
for i := range atcb.builders {
|
||||||
|
func(i int, root context.Context) {
|
||||||
|
builder := atcb.builders[i]
|
||||||
|
builder.defaults()
|
||||||
|
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||||
|
mutation, ok := m.(*ActionTokenMutation)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||||
|
}
|
||||||
|
if err := builder.check(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
builder.mutation = mutation
|
||||||
|
var err error
|
||||||
|
nodes[i], specs[i] = builder.createSpec()
|
||||||
|
if i < len(mutators)-1 {
|
||||||
|
_, err = mutators[i+1].Mutate(root, atcb.builders[i+1].mutation)
|
||||||
|
} else {
|
||||||
|
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||||
|
// Invoke the actual operation on the latest mutation in the chain.
|
||||||
|
if err = sqlgraph.BatchCreate(ctx, atcb.driver, spec); err != nil {
|
||||||
|
if sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mutation.id = &nodes[i].ID
|
||||||
|
mutation.done = true
|
||||||
|
return nodes[i], nil
|
||||||
|
})
|
||||||
|
for i := len(builder.hooks) - 1; i >= 0; i-- {
|
||||||
|
mut = builder.hooks[i](mut)
|
||||||
|
}
|
||||||
|
mutators[i] = mut
|
||||||
|
}(i, ctx)
|
||||||
|
}
|
||||||
|
if len(mutators) > 0 {
|
||||||
|
if _, err := mutators[0].Mutate(ctx, atcb.builders[0].mutation); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
func (atcb *ActionTokenCreateBulk) SaveX(ctx context.Context) []*ActionToken {
|
||||||
|
v, err := atcb.Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the query.
|
||||||
|
func (atcb *ActionTokenCreateBulk) Exec(ctx context.Context) error {
|
||||||
|
_, err := atcb.Save(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (atcb *ActionTokenCreateBulk) ExecX(ctx context.Context) {
|
||||||
|
if err := atcb.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
88
backend/internal/data/ent/actiontoken_delete.go
Normal file
88
backend/internal/data/ent/actiontoken_delete.go
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ActionTokenDelete is the builder for deleting a ActionToken entity.
|
||||||
|
type ActionTokenDelete struct {
|
||||||
|
config
|
||||||
|
hooks []Hook
|
||||||
|
mutation *ActionTokenMutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the ActionTokenDelete builder.
|
||||||
|
func (atd *ActionTokenDelete) Where(ps ...predicate.ActionToken) *ActionTokenDelete {
|
||||||
|
atd.mutation.Where(ps...)
|
||||||
|
return atd
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||||
|
func (atd *ActionTokenDelete) Exec(ctx context.Context) (int, error) {
|
||||||
|
return withHooks(ctx, atd.sqlExec, atd.mutation, atd.hooks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (atd *ActionTokenDelete) ExecX(ctx context.Context) int {
|
||||||
|
n, err := atd.Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atd *ActionTokenDelete) sqlExec(ctx context.Context) (int, error) {
|
||||||
|
_spec := sqlgraph.NewDeleteSpec(actiontoken.Table, sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID))
|
||||||
|
if ps := atd.mutation.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
affected, err := sqlgraph.DeleteNodes(ctx, atd.driver, _spec)
|
||||||
|
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
atd.mutation.done = true
|
||||||
|
return affected, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokenDeleteOne is the builder for deleting a single ActionToken entity.
|
||||||
|
type ActionTokenDeleteOne struct {
|
||||||
|
atd *ActionTokenDelete
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the ActionTokenDelete builder.
|
||||||
|
func (atdo *ActionTokenDeleteOne) Where(ps ...predicate.ActionToken) *ActionTokenDeleteOne {
|
||||||
|
atdo.atd.mutation.Where(ps...)
|
||||||
|
return atdo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the deletion query.
|
||||||
|
func (atdo *ActionTokenDeleteOne) Exec(ctx context.Context) error {
|
||||||
|
n, err := atdo.atd.Exec(ctx)
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
case n == 0:
|
||||||
|
return &NotFoundError{actiontoken.Label}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (atdo *ActionTokenDeleteOne) ExecX(ctx context.Context) {
|
||||||
|
if err := atdo.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
606
backend/internal/data/ent/actiontoken_query.go
Normal file
606
backend/internal/data/ent/actiontoken_query.go
Normal file
|
@ -0,0 +1,606 @@
|
||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ActionTokenQuery is the builder for querying ActionToken entities.
|
||||||
|
type ActionTokenQuery struct {
|
||||||
|
config
|
||||||
|
ctx *QueryContext
|
||||||
|
order []actiontoken.OrderOption
|
||||||
|
inters []Interceptor
|
||||||
|
predicates []predicate.ActionToken
|
||||||
|
withUser *UserQuery
|
||||||
|
// intermediate query (i.e. traversal path).
|
||||||
|
sql *sql.Selector
|
||||||
|
path func(context.Context) (*sql.Selector, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where adds a new predicate for the ActionTokenQuery builder.
|
||||||
|
func (atq *ActionTokenQuery) Where(ps ...predicate.ActionToken) *ActionTokenQuery {
|
||||||
|
atq.predicates = append(atq.predicates, ps...)
|
||||||
|
return atq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit the number of records to be returned by this query.
|
||||||
|
func (atq *ActionTokenQuery) Limit(limit int) *ActionTokenQuery {
|
||||||
|
atq.ctx.Limit = &limit
|
||||||
|
return atq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset to start from.
|
||||||
|
func (atq *ActionTokenQuery) Offset(offset int) *ActionTokenQuery {
|
||||||
|
atq.ctx.Offset = &offset
|
||||||
|
return atq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unique configures the query builder to filter duplicate records on query.
|
||||||
|
// By default, unique is set to true, and can be disabled using this method.
|
||||||
|
func (atq *ActionTokenQuery) Unique(unique bool) *ActionTokenQuery {
|
||||||
|
atq.ctx.Unique = &unique
|
||||||
|
return atq
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order specifies how the records should be ordered.
|
||||||
|
func (atq *ActionTokenQuery) Order(o ...actiontoken.OrderOption) *ActionTokenQuery {
|
||||||
|
atq.order = append(atq.order, o...)
|
||||||
|
return atq
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryUser chains the current query on the "user" edge.
|
||||||
|
func (atq *ActionTokenQuery) QueryUser() *UserQuery {
|
||||||
|
query := (&UserClient{config: atq.config}).Query()
|
||||||
|
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||||
|
if err := atq.prepareQuery(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
selector := atq.sqlQuery(ctx)
|
||||||
|
if err := selector.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(actiontoken.Table, actiontoken.FieldID, selector),
|
||||||
|
sqlgraph.To(user.Table, user.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, actiontoken.UserTable, actiontoken.UserColumn),
|
||||||
|
)
|
||||||
|
fromU = sqlgraph.SetNeighbors(atq.driver.Dialect(), step)
|
||||||
|
return fromU, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// First returns the first ActionToken entity from the query.
|
||||||
|
// Returns a *NotFoundError when no ActionToken was found.
|
||||||
|
func (atq *ActionTokenQuery) First(ctx context.Context) (*ActionToken, error) {
|
||||||
|
nodes, err := atq.Limit(1).All(setContextOp(ctx, atq.ctx, "First"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(nodes) == 0 {
|
||||||
|
return nil, &NotFoundError{actiontoken.Label}
|
||||||
|
}
|
||||||
|
return nodes[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstX is like First, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) FirstX(ctx context.Context) *ActionToken {
|
||||||
|
node, err := atq.First(ctx)
|
||||||
|
if err != nil && !IsNotFound(err) {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstID returns the first ActionToken ID from the query.
|
||||||
|
// Returns a *NotFoundError when no ActionToken ID was found.
|
||||||
|
func (atq *ActionTokenQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||||
|
var ids []uuid.UUID
|
||||||
|
if ids, err = atq.Limit(1).IDs(setContextOp(ctx, atq.ctx, "FirstID")); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(ids) == 0 {
|
||||||
|
err = &NotFoundError{actiontoken.Label}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return ids[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||||
|
id, err := atq.FirstID(ctx)
|
||||||
|
if err != nil && !IsNotFound(err) {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only returns a single ActionToken entity found by the query, ensuring it only returns one.
|
||||||
|
// Returns a *NotSingularError when more than one ActionToken entity is found.
|
||||||
|
// Returns a *NotFoundError when no ActionToken entities are found.
|
||||||
|
func (atq *ActionTokenQuery) Only(ctx context.Context) (*ActionToken, error) {
|
||||||
|
nodes, err := atq.Limit(2).All(setContextOp(ctx, atq.ctx, "Only"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch len(nodes) {
|
||||||
|
case 1:
|
||||||
|
return nodes[0], nil
|
||||||
|
case 0:
|
||||||
|
return nil, &NotFoundError{actiontoken.Label}
|
||||||
|
default:
|
||||||
|
return nil, &NotSingularError{actiontoken.Label}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyX is like Only, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) OnlyX(ctx context.Context) *ActionToken {
|
||||||
|
node, err := atq.Only(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyID is like Only, but returns the only ActionToken ID in the query.
|
||||||
|
// Returns a *NotSingularError when more than one ActionToken ID is found.
|
||||||
|
// Returns a *NotFoundError when no entities are found.
|
||||||
|
func (atq *ActionTokenQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||||
|
var ids []uuid.UUID
|
||||||
|
if ids, err = atq.Limit(2).IDs(setContextOp(ctx, atq.ctx, "OnlyID")); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch len(ids) {
|
||||||
|
case 1:
|
||||||
|
id = ids[0]
|
||||||
|
case 0:
|
||||||
|
err = &NotFoundError{actiontoken.Label}
|
||||||
|
default:
|
||||||
|
err = &NotSingularError{actiontoken.Label}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||||
|
id, err := atq.OnlyID(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// All executes the query and returns a list of ActionTokens.
|
||||||
|
func (atq *ActionTokenQuery) All(ctx context.Context) ([]*ActionToken, error) {
|
||||||
|
ctx = setContextOp(ctx, atq.ctx, "All")
|
||||||
|
if err := atq.prepareQuery(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
qr := querierAll[[]*ActionToken, *ActionTokenQuery]()
|
||||||
|
return withInterceptors[[]*ActionToken](ctx, atq, qr, atq.inters)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllX is like All, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) AllX(ctx context.Context) []*ActionToken {
|
||||||
|
nodes, err := atq.All(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDs executes the query and returns a list of ActionToken IDs.
|
||||||
|
func (atq *ActionTokenQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||||
|
if atq.ctx.Unique == nil && atq.path != nil {
|
||||||
|
atq.Unique(true)
|
||||||
|
}
|
||||||
|
ctx = setContextOp(ctx, atq.ctx, "IDs")
|
||||||
|
if err = atq.Select(actiontoken.FieldID).Scan(ctx, &ids); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ids, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDsX is like IDs, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||||
|
ids, err := atq.IDs(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count returns the count of the given query.
|
||||||
|
func (atq *ActionTokenQuery) Count(ctx context.Context) (int, error) {
|
||||||
|
ctx = setContextOp(ctx, atq.ctx, "Count")
|
||||||
|
if err := atq.prepareQuery(ctx); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return withInterceptors[int](ctx, atq, querierCount[*ActionTokenQuery](), atq.inters)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountX is like Count, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) CountX(ctx context.Context) int {
|
||||||
|
count, err := atq.Count(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exist returns true if the query has elements in the graph.
|
||||||
|
func (atq *ActionTokenQuery) Exist(ctx context.Context) (bool, error) {
|
||||||
|
ctx = setContextOp(ctx, atq.ctx, "Exist")
|
||||||
|
switch _, err := atq.FirstID(ctx); {
|
||||||
|
case IsNotFound(err):
|
||||||
|
return false, nil
|
||||||
|
case err != nil:
|
||||||
|
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||||
|
default:
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExistX is like Exist, but panics if an error occurs.
|
||||||
|
func (atq *ActionTokenQuery) ExistX(ctx context.Context) bool {
|
||||||
|
exist, err := atq.Exist(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return exist
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a duplicate of the ActionTokenQuery builder, including all associated steps. It can be
|
||||||
|
// used to prepare common query builders and use them differently after the clone is made.
|
||||||
|
func (atq *ActionTokenQuery) Clone() *ActionTokenQuery {
|
||||||
|
if atq == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &ActionTokenQuery{
|
||||||
|
config: atq.config,
|
||||||
|
ctx: atq.ctx.Clone(),
|
||||||
|
order: append([]actiontoken.OrderOption{}, atq.order...),
|
||||||
|
inters: append([]Interceptor{}, atq.inters...),
|
||||||
|
predicates: append([]predicate.ActionToken{}, atq.predicates...),
|
||||||
|
withUser: atq.withUser.Clone(),
|
||||||
|
// clone intermediate query.
|
||||||
|
sql: atq.sql.Clone(),
|
||||||
|
path: atq.path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUser tells the query-builder to eager-load the nodes that are connected to
|
||||||
|
// the "user" edge. The optional arguments are used to configure the query builder of the edge.
|
||||||
|
func (atq *ActionTokenQuery) WithUser(opts ...func(*UserQuery)) *ActionTokenQuery {
|
||||||
|
query := (&UserClient{config: atq.config}).Query()
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(query)
|
||||||
|
}
|
||||||
|
atq.withUser = query
|
||||||
|
return atq
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupBy is used to group vertices by one or more fields/columns.
|
||||||
|
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var v []struct {
|
||||||
|
// UserID uuid.UUID `json:"user_id,omitempty"`
|
||||||
|
// Count int `json:"count,omitempty"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// client.ActionToken.Query().
|
||||||
|
// GroupBy(actiontoken.FieldUserID).
|
||||||
|
// Aggregate(ent.Count()).
|
||||||
|
// Scan(ctx, &v)
|
||||||
|
func (atq *ActionTokenQuery) GroupBy(field string, fields ...string) *ActionTokenGroupBy {
|
||||||
|
atq.ctx.Fields = append([]string{field}, fields...)
|
||||||
|
grbuild := &ActionTokenGroupBy{build: atq}
|
||||||
|
grbuild.flds = &atq.ctx.Fields
|
||||||
|
grbuild.label = actiontoken.Label
|
||||||
|
grbuild.scan = grbuild.Scan
|
||||||
|
return grbuild
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select allows the selection one or more fields/columns for the given query,
|
||||||
|
// instead of selecting all fields in the entity.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var v []struct {
|
||||||
|
// UserID uuid.UUID `json:"user_id,omitempty"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// client.ActionToken.Query().
|
||||||
|
// Select(actiontoken.FieldUserID).
|
||||||
|
// Scan(ctx, &v)
|
||||||
|
func (atq *ActionTokenQuery) Select(fields ...string) *ActionTokenSelect {
|
||||||
|
atq.ctx.Fields = append(atq.ctx.Fields, fields...)
|
||||||
|
sbuild := &ActionTokenSelect{ActionTokenQuery: atq}
|
||||||
|
sbuild.label = actiontoken.Label
|
||||||
|
sbuild.flds, sbuild.scan = &atq.ctx.Fields, sbuild.Scan
|
||||||
|
return sbuild
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate returns a ActionTokenSelect configured with the given aggregations.
|
||||||
|
func (atq *ActionTokenQuery) Aggregate(fns ...AggregateFunc) *ActionTokenSelect {
|
||||||
|
return atq.Select().Aggregate(fns...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atq *ActionTokenQuery) prepareQuery(ctx context.Context) error {
|
||||||
|
for _, inter := range atq.inters {
|
||||||
|
if inter == nil {
|
||||||
|
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||||
|
}
|
||||||
|
if trv, ok := inter.(Traverser); ok {
|
||||||
|
if err := trv.Traverse(ctx, atq); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, f := range atq.ctx.Fields {
|
||||||
|
if !actiontoken.ValidColumn(f) {
|
||||||
|
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if atq.path != nil {
|
||||||
|
prev, err := atq.path(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
atq.sql = prev
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atq *ActionTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*ActionToken, error) {
|
||||||
|
var (
|
||||||
|
nodes = []*ActionToken{}
|
||||||
|
_spec = atq.querySpec()
|
||||||
|
loadedTypes = [1]bool{
|
||||||
|
atq.withUser != nil,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||||
|
return (*ActionToken).scanValues(nil, columns)
|
||||||
|
}
|
||||||
|
_spec.Assign = func(columns []string, values []any) error {
|
||||||
|
node := &ActionToken{config: atq.config}
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
node.Edges.loadedTypes = loadedTypes
|
||||||
|
return node.assignValues(columns, values)
|
||||||
|
}
|
||||||
|
for i := range hooks {
|
||||||
|
hooks[i](ctx, _spec)
|
||||||
|
}
|
||||||
|
if err := sqlgraph.QueryNodes(ctx, atq.driver, _spec); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(nodes) == 0 {
|
||||||
|
return nodes, nil
|
||||||
|
}
|
||||||
|
if query := atq.withUser; query != nil {
|
||||||
|
if err := atq.loadUser(ctx, query, nodes, nil,
|
||||||
|
func(n *ActionToken, e *User) { n.Edges.User = e }); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atq *ActionTokenQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*ActionToken, init func(*ActionToken), assign func(*ActionToken, *User)) error {
|
||||||
|
ids := make([]uuid.UUID, 0, len(nodes))
|
||||||
|
nodeids := make(map[uuid.UUID][]*ActionToken)
|
||||||
|
for i := range nodes {
|
||||||
|
fk := nodes[i].UserID
|
||||||
|
if _, ok := nodeids[fk]; !ok {
|
||||||
|
ids = append(ids, fk)
|
||||||
|
}
|
||||||
|
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||||
|
}
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
query.Where(user.IDIn(ids...))
|
||||||
|
neighbors, err := query.All(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, n := range neighbors {
|
||||||
|
nodes, ok := nodeids[n.ID]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf(`unexpected foreign-key "user_id" returned %v`, n.ID)
|
||||||
|
}
|
||||||
|
for i := range nodes {
|
||||||
|
assign(nodes[i], n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atq *ActionTokenQuery) sqlCount(ctx context.Context) (int, error) {
|
||||||
|
_spec := atq.querySpec()
|
||||||
|
_spec.Node.Columns = atq.ctx.Fields
|
||||||
|
if len(atq.ctx.Fields) > 0 {
|
||||||
|
_spec.Unique = atq.ctx.Unique != nil && *atq.ctx.Unique
|
||||||
|
}
|
||||||
|
return sqlgraph.CountNodes(ctx, atq.driver, _spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atq *ActionTokenQuery) querySpec() *sqlgraph.QuerySpec {
|
||||||
|
_spec := sqlgraph.NewQuerySpec(actiontoken.Table, actiontoken.Columns, sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID))
|
||||||
|
_spec.From = atq.sql
|
||||||
|
if unique := atq.ctx.Unique; unique != nil {
|
||||||
|
_spec.Unique = *unique
|
||||||
|
} else if atq.path != nil {
|
||||||
|
_spec.Unique = true
|
||||||
|
}
|
||||||
|
if fields := atq.ctx.Fields; len(fields) > 0 {
|
||||||
|
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, actiontoken.FieldID)
|
||||||
|
for i := range fields {
|
||||||
|
if fields[i] != actiontoken.FieldID {
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if atq.withUser != nil {
|
||||||
|
_spec.Node.AddColumnOnce(actiontoken.FieldUserID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ps := atq.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if limit := atq.ctx.Limit; limit != nil {
|
||||||
|
_spec.Limit = *limit
|
||||||
|
}
|
||||||
|
if offset := atq.ctx.Offset; offset != nil {
|
||||||
|
_spec.Offset = *offset
|
||||||
|
}
|
||||||
|
if ps := atq.order; len(ps) > 0 {
|
||||||
|
_spec.Order = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _spec
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atq *ActionTokenQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||||
|
builder := sql.Dialect(atq.driver.Dialect())
|
||||||
|
t1 := builder.Table(actiontoken.Table)
|
||||||
|
columns := atq.ctx.Fields
|
||||||
|
if len(columns) == 0 {
|
||||||
|
columns = actiontoken.Columns
|
||||||
|
}
|
||||||
|
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||||
|
if atq.sql != nil {
|
||||||
|
selector = atq.sql
|
||||||
|
selector.Select(selector.Columns(columns...)...)
|
||||||
|
}
|
||||||
|
if atq.ctx.Unique != nil && *atq.ctx.Unique {
|
||||||
|
selector.Distinct()
|
||||||
|
}
|
||||||
|
for _, p := range atq.predicates {
|
||||||
|
p(selector)
|
||||||
|
}
|
||||||
|
for _, p := range atq.order {
|
||||||
|
p(selector)
|
||||||
|
}
|
||||||
|
if offset := atq.ctx.Offset; offset != nil {
|
||||||
|
// limit is mandatory for offset clause. We start
|
||||||
|
// with default value, and override it below if needed.
|
||||||
|
selector.Offset(*offset).Limit(math.MaxInt32)
|
||||||
|
}
|
||||||
|
if limit := atq.ctx.Limit; limit != nil {
|
||||||
|
selector.Limit(*limit)
|
||||||
|
}
|
||||||
|
return selector
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokenGroupBy is the group-by builder for ActionToken entities.
|
||||||
|
type ActionTokenGroupBy struct {
|
||||||
|
selector
|
||||||
|
build *ActionTokenQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate adds the given aggregation functions to the group-by query.
|
||||||
|
func (atgb *ActionTokenGroupBy) Aggregate(fns ...AggregateFunc) *ActionTokenGroupBy {
|
||||||
|
atgb.fns = append(atgb.fns, fns...)
|
||||||
|
return atgb
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan applies the selector query and scans the result into the given value.
|
||||||
|
func (atgb *ActionTokenGroupBy) Scan(ctx context.Context, v any) error {
|
||||||
|
ctx = setContextOp(ctx, atgb.build.ctx, "GroupBy")
|
||||||
|
if err := atgb.build.prepareQuery(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return scanWithInterceptors[*ActionTokenQuery, *ActionTokenGroupBy](ctx, atgb.build, atgb, atgb.build.inters, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atgb *ActionTokenGroupBy) sqlScan(ctx context.Context, root *ActionTokenQuery, v any) error {
|
||||||
|
selector := root.sqlQuery(ctx).Select()
|
||||||
|
aggregation := make([]string, 0, len(atgb.fns))
|
||||||
|
for _, fn := range atgb.fns {
|
||||||
|
aggregation = append(aggregation, fn(selector))
|
||||||
|
}
|
||||||
|
if len(selector.SelectedColumns()) == 0 {
|
||||||
|
columns := make([]string, 0, len(*atgb.flds)+len(atgb.fns))
|
||||||
|
for _, f := range *atgb.flds {
|
||||||
|
columns = append(columns, selector.C(f))
|
||||||
|
}
|
||||||
|
columns = append(columns, aggregation...)
|
||||||
|
selector.Select(columns...)
|
||||||
|
}
|
||||||
|
selector.GroupBy(selector.Columns(*atgb.flds...)...)
|
||||||
|
if err := selector.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows := &sql.Rows{}
|
||||||
|
query, args := selector.Query()
|
||||||
|
if err := atgb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
return sql.ScanSlice(rows, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokenSelect is the builder for selecting fields of ActionToken entities.
|
||||||
|
type ActionTokenSelect struct {
|
||||||
|
*ActionTokenQuery
|
||||||
|
selector
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate adds the given aggregation functions to the selector query.
|
||||||
|
func (ats *ActionTokenSelect) Aggregate(fns ...AggregateFunc) *ActionTokenSelect {
|
||||||
|
ats.fns = append(ats.fns, fns...)
|
||||||
|
return ats
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan applies the selector query and scans the result into the given value.
|
||||||
|
func (ats *ActionTokenSelect) Scan(ctx context.Context, v any) error {
|
||||||
|
ctx = setContextOp(ctx, ats.ctx, "Select")
|
||||||
|
if err := ats.prepareQuery(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return scanWithInterceptors[*ActionTokenQuery, *ActionTokenSelect](ctx, ats.ActionTokenQuery, ats, ats.inters, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ats *ActionTokenSelect) sqlScan(ctx context.Context, root *ActionTokenQuery, v any) error {
|
||||||
|
selector := root.sqlQuery(ctx)
|
||||||
|
aggregation := make([]string, 0, len(ats.fns))
|
||||||
|
for _, fn := range ats.fns {
|
||||||
|
aggregation = append(aggregation, fn(selector))
|
||||||
|
}
|
||||||
|
switch n := len(*ats.selector.flds); {
|
||||||
|
case n == 0 && len(aggregation) > 0:
|
||||||
|
selector.Select(aggregation...)
|
||||||
|
case n != 0 && len(aggregation) > 0:
|
||||||
|
selector.AppendSelect(aggregation...)
|
||||||
|
}
|
||||||
|
rows := &sql.Rows{}
|
||||||
|
query, args := selector.Query()
|
||||||
|
if err := ats.driver.Query(ctx, query, args, rows); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
return sql.ScanSlice(rows, v)
|
||||||
|
}
|
406
backend/internal/data/ent/actiontoken_update.go
Normal file
406
backend/internal/data/ent/actiontoken_update.go
Normal file
|
@ -0,0 +1,406 @@
|
||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"entgo.io/ent/dialect/sql"
|
||||||
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ActionTokenUpdate is the builder for updating ActionToken entities.
|
||||||
|
type ActionTokenUpdate struct {
|
||||||
|
config
|
||||||
|
hooks []Hook
|
||||||
|
mutation *ActionTokenMutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the ActionTokenUpdate builder.
|
||||||
|
func (atu *ActionTokenUpdate) Where(ps ...predicate.ActionToken) *ActionTokenUpdate {
|
||||||
|
atu.mutation.Where(ps...)
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserID sets the "user_id" field.
|
||||||
|
func (atu *ActionTokenUpdate) SetUserID(u uuid.UUID) *ActionTokenUpdate {
|
||||||
|
atu.mutation.SetUserID(u)
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableUserID sets the "user_id" field if the given value is not nil.
|
||||||
|
func (atu *ActionTokenUpdate) SetNillableUserID(u *uuid.UUID) *ActionTokenUpdate {
|
||||||
|
if u != nil {
|
||||||
|
atu.SetUserID(*u)
|
||||||
|
}
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUpdatedAt sets the "updated_at" field.
|
||||||
|
func (atu *ActionTokenUpdate) SetUpdatedAt(t time.Time) *ActionTokenUpdate {
|
||||||
|
atu.mutation.SetUpdatedAt(t)
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAction sets the "action" field.
|
||||||
|
func (atu *ActionTokenUpdate) SetAction(a actiontoken.Action) *ActionTokenUpdate {
|
||||||
|
atu.mutation.SetAction(a)
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableAction sets the "action" field if the given value is not nil.
|
||||||
|
func (atu *ActionTokenUpdate) SetNillableAction(a *actiontoken.Action) *ActionTokenUpdate {
|
||||||
|
if a != nil {
|
||||||
|
atu.SetAction(*a)
|
||||||
|
}
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToken sets the "token" field.
|
||||||
|
func (atu *ActionTokenUpdate) SetToken(b []byte) *ActionTokenUpdate {
|
||||||
|
atu.mutation.SetToken(b)
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUser sets the "user" edge to the User entity.
|
||||||
|
func (atu *ActionTokenUpdate) SetUser(u *User) *ActionTokenUpdate {
|
||||||
|
return atu.SetUserID(u.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutation returns the ActionTokenMutation object of the builder.
|
||||||
|
func (atu *ActionTokenUpdate) Mutation() *ActionTokenMutation {
|
||||||
|
return atu.mutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearUser clears the "user" edge to the User entity.
|
||||||
|
func (atu *ActionTokenUpdate) ClearUser() *ActionTokenUpdate {
|
||||||
|
atu.mutation.ClearUser()
|
||||||
|
return atu
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
|
func (atu *ActionTokenUpdate) Save(ctx context.Context) (int, error) {
|
||||||
|
atu.defaults()
|
||||||
|
return withHooks(ctx, atu.sqlSave, atu.mutation, atu.hooks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
func (atu *ActionTokenUpdate) SaveX(ctx context.Context) int {
|
||||||
|
affected, err := atu.Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return affected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the query.
|
||||||
|
func (atu *ActionTokenUpdate) Exec(ctx context.Context) error {
|
||||||
|
_, err := atu.Save(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (atu *ActionTokenUpdate) ExecX(ctx context.Context) {
|
||||||
|
if err := atu.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaults sets the default values of the builder before save.
|
||||||
|
func (atu *ActionTokenUpdate) defaults() {
|
||||||
|
if _, ok := atu.mutation.UpdatedAt(); !ok {
|
||||||
|
v := actiontoken.UpdateDefaultUpdatedAt()
|
||||||
|
atu.mutation.SetUpdatedAt(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check runs all checks and user-defined validators on the builder.
|
||||||
|
func (atu *ActionTokenUpdate) check() error {
|
||||||
|
if v, ok := atu.mutation.Action(); ok {
|
||||||
|
if err := actiontoken.ActionValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "ActionToken.action": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, ok := atu.mutation.UserID(); atu.mutation.UserCleared() && !ok {
|
||||||
|
return errors.New(`ent: clearing a required unique edge "ActionToken.user"`)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atu *ActionTokenUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
|
if err := atu.check(); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
_spec := sqlgraph.NewUpdateSpec(actiontoken.Table, actiontoken.Columns, sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID))
|
||||||
|
if ps := atu.mutation.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if value, ok := atu.mutation.UpdatedAt(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldUpdatedAt, field.TypeTime, value)
|
||||||
|
}
|
||||||
|
if value, ok := atu.mutation.Action(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldAction, field.TypeEnum, value)
|
||||||
|
}
|
||||||
|
if value, ok := atu.mutation.Token(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldToken, field.TypeBytes, value)
|
||||||
|
}
|
||||||
|
if atu.mutation.UserCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.M2O,
|
||||||
|
Inverse: true,
|
||||||
|
Table: actiontoken.UserTable,
|
||||||
|
Columns: []string{actiontoken.UserColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := atu.mutation.UserIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.M2O,
|
||||||
|
Inverse: true,
|
||||||
|
Table: actiontoken.UserTable,
|
||||||
|
Columns: []string{actiontoken.UserColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
|
}
|
||||||
|
if n, err = sqlgraph.UpdateNodes(ctx, atu.driver, _spec); err != nil {
|
||||||
|
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||||
|
err = &NotFoundError{actiontoken.Label}
|
||||||
|
} else if sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
atu.mutation.done = true
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokenUpdateOne is the builder for updating a single ActionToken entity.
|
||||||
|
type ActionTokenUpdateOne struct {
|
||||||
|
config
|
||||||
|
fields []string
|
||||||
|
hooks []Hook
|
||||||
|
mutation *ActionTokenMutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserID sets the "user_id" field.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SetUserID(u uuid.UUID) *ActionTokenUpdateOne {
|
||||||
|
atuo.mutation.SetUserID(u)
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableUserID sets the "user_id" field if the given value is not nil.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SetNillableUserID(u *uuid.UUID) *ActionTokenUpdateOne {
|
||||||
|
if u != nil {
|
||||||
|
atuo.SetUserID(*u)
|
||||||
|
}
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUpdatedAt sets the "updated_at" field.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SetUpdatedAt(t time.Time) *ActionTokenUpdateOne {
|
||||||
|
atuo.mutation.SetUpdatedAt(t)
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAction sets the "action" field.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SetAction(a actiontoken.Action) *ActionTokenUpdateOne {
|
||||||
|
atuo.mutation.SetAction(a)
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableAction sets the "action" field if the given value is not nil.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SetNillableAction(a *actiontoken.Action) *ActionTokenUpdateOne {
|
||||||
|
if a != nil {
|
||||||
|
atuo.SetAction(*a)
|
||||||
|
}
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToken sets the "token" field.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SetToken(b []byte) *ActionTokenUpdateOne {
|
||||||
|
atuo.mutation.SetToken(b)
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUser sets the "user" edge to the User entity.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SetUser(u *User) *ActionTokenUpdateOne {
|
||||||
|
return atuo.SetUserID(u.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutation returns the ActionTokenMutation object of the builder.
|
||||||
|
func (atuo *ActionTokenUpdateOne) Mutation() *ActionTokenMutation {
|
||||||
|
return atuo.mutation
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearUser clears the "user" edge to the User entity.
|
||||||
|
func (atuo *ActionTokenUpdateOne) ClearUser() *ActionTokenUpdateOne {
|
||||||
|
atuo.mutation.ClearUser()
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the ActionTokenUpdate builder.
|
||||||
|
func (atuo *ActionTokenUpdateOne) Where(ps ...predicate.ActionToken) *ActionTokenUpdateOne {
|
||||||
|
atuo.mutation.Where(ps...)
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||||
|
// The default is selecting all fields defined in the entity schema.
|
||||||
|
func (atuo *ActionTokenUpdateOne) Select(field string, fields ...string) *ActionTokenUpdateOne {
|
||||||
|
atuo.fields = append([]string{field}, fields...)
|
||||||
|
return atuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save executes the query and returns the updated ActionToken entity.
|
||||||
|
func (atuo *ActionTokenUpdateOne) Save(ctx context.Context) (*ActionToken, error) {
|
||||||
|
atuo.defaults()
|
||||||
|
return withHooks(ctx, atuo.sqlSave, atuo.mutation, atuo.hooks)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveX is like Save, but panics if an error occurs.
|
||||||
|
func (atuo *ActionTokenUpdateOne) SaveX(ctx context.Context) *ActionToken {
|
||||||
|
node, err := atuo.Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exec executes the query on the entity.
|
||||||
|
func (atuo *ActionTokenUpdateOne) Exec(ctx context.Context) error {
|
||||||
|
_, err := atuo.Save(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecX is like Exec, but panics if an error occurs.
|
||||||
|
func (atuo *ActionTokenUpdateOne) ExecX(ctx context.Context) {
|
||||||
|
if err := atuo.Exec(ctx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaults sets the default values of the builder before save.
|
||||||
|
func (atuo *ActionTokenUpdateOne) defaults() {
|
||||||
|
if _, ok := atuo.mutation.UpdatedAt(); !ok {
|
||||||
|
v := actiontoken.UpdateDefaultUpdatedAt()
|
||||||
|
atuo.mutation.SetUpdatedAt(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check runs all checks and user-defined validators on the builder.
|
||||||
|
func (atuo *ActionTokenUpdateOne) check() error {
|
||||||
|
if v, ok := atuo.mutation.Action(); ok {
|
||||||
|
if err := actiontoken.ActionValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "action", err: fmt.Errorf(`ent: validator failed for field "ActionToken.action": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, ok := atuo.mutation.UserID(); atuo.mutation.UserCleared() && !ok {
|
||||||
|
return errors.New(`ent: clearing a required unique edge "ActionToken.user"`)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (atuo *ActionTokenUpdateOne) sqlSave(ctx context.Context) (_node *ActionToken, err error) {
|
||||||
|
if err := atuo.check(); err != nil {
|
||||||
|
return _node, err
|
||||||
|
}
|
||||||
|
_spec := sqlgraph.NewUpdateSpec(actiontoken.Table, actiontoken.Columns, sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID))
|
||||||
|
id, ok := atuo.mutation.ID()
|
||||||
|
if !ok {
|
||||||
|
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "ActionToken.id" for update`)}
|
||||||
|
}
|
||||||
|
_spec.Node.ID.Value = id
|
||||||
|
if fields := atuo.fields; len(fields) > 0 {
|
||||||
|
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, actiontoken.FieldID)
|
||||||
|
for _, f := range fields {
|
||||||
|
if !actiontoken.ValidColumn(f) {
|
||||||
|
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||||
|
}
|
||||||
|
if f != actiontoken.FieldID {
|
||||||
|
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ps := atuo.mutation.predicates; len(ps) > 0 {
|
||||||
|
_spec.Predicate = func(selector *sql.Selector) {
|
||||||
|
for i := range ps {
|
||||||
|
ps[i](selector)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if value, ok := atuo.mutation.UpdatedAt(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldUpdatedAt, field.TypeTime, value)
|
||||||
|
}
|
||||||
|
if value, ok := atuo.mutation.Action(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldAction, field.TypeEnum, value)
|
||||||
|
}
|
||||||
|
if value, ok := atuo.mutation.Token(); ok {
|
||||||
|
_spec.SetField(actiontoken.FieldToken, field.TypeBytes, value)
|
||||||
|
}
|
||||||
|
if atuo.mutation.UserCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.M2O,
|
||||||
|
Inverse: true,
|
||||||
|
Table: actiontoken.UserTable,
|
||||||
|
Columns: []string{actiontoken.UserColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := atuo.mutation.UserIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.M2O,
|
||||||
|
Inverse: true,
|
||||||
|
Table: actiontoken.UserTable,
|
||||||
|
Columns: []string{actiontoken.UserColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
|
}
|
||||||
|
_node = &ActionToken{config: atuo.config}
|
||||||
|
_spec.Assign = _node.assignValues
|
||||||
|
_spec.ScanValues = _node.scanValues
|
||||||
|
if err = sqlgraph.UpdateNode(ctx, atuo.driver, _spec); err != nil {
|
||||||
|
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||||
|
err = &NotFoundError{actiontoken.Label}
|
||||||
|
} else if sqlgraph.IsConstraintError(err) {
|
||||||
|
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
atuo.mutation.done = true
|
||||||
|
return _node, nil
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"entgo.io/ent/dialect"
|
"entgo.io/ent/dialect"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
|
@ -36,6 +37,8 @@ type Client struct {
|
||||||
config
|
config
|
||||||
// Schema is the client for creating, migrating and dropping schema.
|
// Schema is the client for creating, migrating and dropping schema.
|
||||||
Schema *migrate.Schema
|
Schema *migrate.Schema
|
||||||
|
// ActionToken is the client for interacting with the ActionToken builders.
|
||||||
|
ActionToken *ActionTokenClient
|
||||||
// Attachment is the client for interacting with the Attachment builders.
|
// Attachment is the client for interacting with the Attachment builders.
|
||||||
Attachment *AttachmentClient
|
Attachment *AttachmentClient
|
||||||
// AuthRoles is the client for interacting with the AuthRoles builders.
|
// AuthRoles is the client for interacting with the AuthRoles builders.
|
||||||
|
@ -73,6 +76,7 @@ func NewClient(opts ...Option) *Client {
|
||||||
|
|
||||||
func (c *Client) init() {
|
func (c *Client) init() {
|
||||||
c.Schema = migrate.NewSchema(c.driver)
|
c.Schema = migrate.NewSchema(c.driver)
|
||||||
|
c.ActionToken = NewActionTokenClient(c.config)
|
||||||
c.Attachment = NewAttachmentClient(c.config)
|
c.Attachment = NewAttachmentClient(c.config)
|
||||||
c.AuthRoles = NewAuthRolesClient(c.config)
|
c.AuthRoles = NewAuthRolesClient(c.config)
|
||||||
c.AuthTokens = NewAuthTokensClient(c.config)
|
c.AuthTokens = NewAuthTokensClient(c.config)
|
||||||
|
@ -178,6 +182,7 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
|
||||||
return &Tx{
|
return &Tx{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
config: cfg,
|
config: cfg,
|
||||||
|
ActionToken: NewActionTokenClient(cfg),
|
||||||
Attachment: NewAttachmentClient(cfg),
|
Attachment: NewAttachmentClient(cfg),
|
||||||
AuthRoles: NewAuthRolesClient(cfg),
|
AuthRoles: NewAuthRolesClient(cfg),
|
||||||
AuthTokens: NewAuthTokensClient(cfg),
|
AuthTokens: NewAuthTokensClient(cfg),
|
||||||
|
@ -210,6 +215,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
|
||||||
return &Tx{
|
return &Tx{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
config: cfg,
|
config: cfg,
|
||||||
|
ActionToken: NewActionTokenClient(cfg),
|
||||||
Attachment: NewAttachmentClient(cfg),
|
Attachment: NewAttachmentClient(cfg),
|
||||||
AuthRoles: NewAuthRolesClient(cfg),
|
AuthRoles: NewAuthRolesClient(cfg),
|
||||||
AuthTokens: NewAuthTokensClient(cfg),
|
AuthTokens: NewAuthTokensClient(cfg),
|
||||||
|
@ -229,7 +235,7 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
|
||||||
// Debug returns a new debug-client. It's used to get verbose logging on specific operations.
|
// Debug returns a new debug-client. It's used to get verbose logging on specific operations.
|
||||||
//
|
//
|
||||||
// client.Debug().
|
// client.Debug().
|
||||||
// Attachment.
|
// ActionToken.
|
||||||
// Query().
|
// Query().
|
||||||
// Count(ctx)
|
// Count(ctx)
|
||||||
func (c *Client) Debug() *Client {
|
func (c *Client) Debug() *Client {
|
||||||
|
@ -252,7 +258,7 @@ func (c *Client) Close() error {
|
||||||
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
|
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
|
||||||
func (c *Client) Use(hooks ...Hook) {
|
func (c *Client) Use(hooks ...Hook) {
|
||||||
for _, n := range []interface{ Use(...Hook) }{
|
for _, n := range []interface{ Use(...Hook) }{
|
||||||
c.Attachment, c.AuthRoles, c.AuthTokens, c.Document, c.Group,
|
c.ActionToken, c.Attachment, c.AuthRoles, c.AuthTokens, c.Document, c.Group,
|
||||||
c.GroupInvitationToken, c.Item, c.ItemField, c.Label, c.Location,
|
c.GroupInvitationToken, c.Item, c.ItemField, c.Label, c.Location,
|
||||||
c.MaintenanceEntry, c.Notifier, c.User,
|
c.MaintenanceEntry, c.Notifier, c.User,
|
||||||
} {
|
} {
|
||||||
|
@ -264,7 +270,7 @@ func (c *Client) Use(hooks ...Hook) {
|
||||||
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
|
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
|
||||||
func (c *Client) Intercept(interceptors ...Interceptor) {
|
func (c *Client) Intercept(interceptors ...Interceptor) {
|
||||||
for _, n := range []interface{ Intercept(...Interceptor) }{
|
for _, n := range []interface{ Intercept(...Interceptor) }{
|
||||||
c.Attachment, c.AuthRoles, c.AuthTokens, c.Document, c.Group,
|
c.ActionToken, c.Attachment, c.AuthRoles, c.AuthTokens, c.Document, c.Group,
|
||||||
c.GroupInvitationToken, c.Item, c.ItemField, c.Label, c.Location,
|
c.GroupInvitationToken, c.Item, c.ItemField, c.Label, c.Location,
|
||||||
c.MaintenanceEntry, c.Notifier, c.User,
|
c.MaintenanceEntry, c.Notifier, c.User,
|
||||||
} {
|
} {
|
||||||
|
@ -275,6 +281,8 @@ func (c *Client) Intercept(interceptors ...Interceptor) {
|
||||||
// Mutate implements the ent.Mutator interface.
|
// Mutate implements the ent.Mutator interface.
|
||||||
func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
|
func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
|
||||||
switch m := m.(type) {
|
switch m := m.(type) {
|
||||||
|
case *ActionTokenMutation:
|
||||||
|
return c.ActionToken.mutate(ctx, m)
|
||||||
case *AttachmentMutation:
|
case *AttachmentMutation:
|
||||||
return c.Attachment.mutate(ctx, m)
|
return c.Attachment.mutate(ctx, m)
|
||||||
case *AuthRolesMutation:
|
case *AuthRolesMutation:
|
||||||
|
@ -306,6 +314,155 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionTokenClient is a client for the ActionToken schema.
|
||||||
|
type ActionTokenClient struct {
|
||||||
|
config
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewActionTokenClient returns a client for the ActionToken from the given config.
|
||||||
|
func NewActionTokenClient(c config) *ActionTokenClient {
|
||||||
|
return &ActionTokenClient{config: c}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use adds a list of mutation hooks to the hooks stack.
|
||||||
|
// A call to `Use(f, g, h)` equals to `actiontoken.Hooks(f(g(h())))`.
|
||||||
|
func (c *ActionTokenClient) Use(hooks ...Hook) {
|
||||||
|
c.hooks.ActionToken = append(c.hooks.ActionToken, hooks...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intercept adds a list of query interceptors to the interceptors stack.
|
||||||
|
// A call to `Intercept(f, g, h)` equals to `actiontoken.Intercept(f(g(h())))`.
|
||||||
|
func (c *ActionTokenClient) Intercept(interceptors ...Interceptor) {
|
||||||
|
c.inters.ActionToken = append(c.inters.ActionToken, interceptors...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create returns a builder for creating a ActionToken entity.
|
||||||
|
func (c *ActionTokenClient) Create() *ActionTokenCreate {
|
||||||
|
mutation := newActionTokenMutation(c.config, OpCreate)
|
||||||
|
return &ActionTokenCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateBulk returns a builder for creating a bulk of ActionToken entities.
|
||||||
|
func (c *ActionTokenClient) CreateBulk(builders ...*ActionTokenCreate) *ActionTokenCreateBulk {
|
||||||
|
return &ActionTokenCreateBulk{config: c.config, builders: builders}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
|
||||||
|
// a builder and applies setFunc on it.
|
||||||
|
func (c *ActionTokenClient) MapCreateBulk(slice any, setFunc func(*ActionTokenCreate, int)) *ActionTokenCreateBulk {
|
||||||
|
rv := reflect.ValueOf(slice)
|
||||||
|
if rv.Kind() != reflect.Slice {
|
||||||
|
return &ActionTokenCreateBulk{err: fmt.Errorf("calling to ActionTokenClient.MapCreateBulk with wrong type %T, need slice", slice)}
|
||||||
|
}
|
||||||
|
builders := make([]*ActionTokenCreate, rv.Len())
|
||||||
|
for i := 0; i < rv.Len(); i++ {
|
||||||
|
builders[i] = c.Create()
|
||||||
|
setFunc(builders[i], i)
|
||||||
|
}
|
||||||
|
return &ActionTokenCreateBulk{config: c.config, builders: builders}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update returns an update builder for ActionToken.
|
||||||
|
func (c *ActionTokenClient) Update() *ActionTokenUpdate {
|
||||||
|
mutation := newActionTokenMutation(c.config, OpUpdate)
|
||||||
|
return &ActionTokenUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOne returns an update builder for the given entity.
|
||||||
|
func (c *ActionTokenClient) UpdateOne(at *ActionToken) *ActionTokenUpdateOne {
|
||||||
|
mutation := newActionTokenMutation(c.config, OpUpdateOne, withActionToken(at))
|
||||||
|
return &ActionTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateOneID returns an update builder for the given id.
|
||||||
|
func (c *ActionTokenClient) UpdateOneID(id uuid.UUID) *ActionTokenUpdateOne {
|
||||||
|
mutation := newActionTokenMutation(c.config, OpUpdateOne, withActionTokenID(id))
|
||||||
|
return &ActionTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete returns a delete builder for ActionToken.
|
||||||
|
func (c *ActionTokenClient) Delete() *ActionTokenDelete {
|
||||||
|
mutation := newActionTokenMutation(c.config, OpDelete)
|
||||||
|
return &ActionTokenDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOne returns a builder for deleting the given entity.
|
||||||
|
func (c *ActionTokenClient) DeleteOne(at *ActionToken) *ActionTokenDeleteOne {
|
||||||
|
return c.DeleteOneID(at.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOneID returns a builder for deleting the given entity by its id.
|
||||||
|
func (c *ActionTokenClient) DeleteOneID(id uuid.UUID) *ActionTokenDeleteOne {
|
||||||
|
builder := c.Delete().Where(actiontoken.ID(id))
|
||||||
|
builder.mutation.id = &id
|
||||||
|
builder.mutation.op = OpDeleteOne
|
||||||
|
return &ActionTokenDeleteOne{builder}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query returns a query builder for ActionToken.
|
||||||
|
func (c *ActionTokenClient) Query() *ActionTokenQuery {
|
||||||
|
return &ActionTokenQuery{
|
||||||
|
config: c.config,
|
||||||
|
ctx: &QueryContext{Type: TypeActionToken},
|
||||||
|
inters: c.Interceptors(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns a ActionToken entity by its id.
|
||||||
|
func (c *ActionTokenClient) Get(ctx context.Context, id uuid.UUID) (*ActionToken, error) {
|
||||||
|
return c.Query().Where(actiontoken.ID(id)).Only(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetX is like Get, but panics if an error occurs.
|
||||||
|
func (c *ActionTokenClient) GetX(ctx context.Context, id uuid.UUID) *ActionToken {
|
||||||
|
obj, err := c.Get(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryUser queries the user edge of a ActionToken.
|
||||||
|
func (c *ActionTokenClient) QueryUser(at *ActionToken) *UserQuery {
|
||||||
|
query := (&UserClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := at.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(actiontoken.Table, actiontoken.FieldID, id),
|
||||||
|
sqlgraph.To(user.Table, user.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.M2O, true, actiontoken.UserTable, actiontoken.UserColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(at.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hooks returns the client hooks.
|
||||||
|
func (c *ActionTokenClient) Hooks() []Hook {
|
||||||
|
return c.hooks.ActionToken
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interceptors returns the client interceptors.
|
||||||
|
func (c *ActionTokenClient) Interceptors() []Interceptor {
|
||||||
|
return c.inters.ActionToken
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ActionTokenClient) mutate(ctx context.Context, m *ActionTokenMutation) (Value, error) {
|
||||||
|
switch m.Op() {
|
||||||
|
case OpCreate:
|
||||||
|
return (&ActionTokenCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||||
|
case OpUpdate:
|
||||||
|
return (&ActionTokenUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||||
|
case OpUpdateOne:
|
||||||
|
return (&ActionTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||||
|
case OpDelete, OpDeleteOne:
|
||||||
|
return (&ActionTokenDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("ent: unknown ActionToken mutation op: %q", m.Op())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AttachmentClient is a client for the Attachment schema.
|
// AttachmentClient is a client for the Attachment schema.
|
||||||
type AttachmentClient struct {
|
type AttachmentClient struct {
|
||||||
config
|
config
|
||||||
|
@ -2586,6 +2743,22 @@ func (c *UserClient) QueryNotifiers(u *User) *NotifierQuery {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryActionTokens queries the action_tokens edge of a User.
|
||||||
|
func (c *UserClient) QueryActionTokens(u *User) *ActionTokenQuery {
|
||||||
|
query := (&ActionTokenClient{config: c.config}).Query()
|
||||||
|
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||||
|
id := u.ID
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(user.Table, user.FieldID, id),
|
||||||
|
sqlgraph.To(actiontoken.Table, actiontoken.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, user.ActionTokensTable, user.ActionTokensColumn),
|
||||||
|
)
|
||||||
|
fromV = sqlgraph.Neighbors(u.driver.Dialect(), step)
|
||||||
|
return fromV, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
// Hooks returns the client hooks.
|
// Hooks returns the client hooks.
|
||||||
func (c *UserClient) Hooks() []Hook {
|
func (c *UserClient) Hooks() []Hook {
|
||||||
return c.hooks.User
|
return c.hooks.User
|
||||||
|
@ -2614,11 +2787,13 @@ func (c *UserClient) mutate(ctx context.Context, m *UserMutation) (Value, error)
|
||||||
// hooks and interceptors per client, for fast access.
|
// hooks and interceptors per client, for fast access.
|
||||||
type (
|
type (
|
||||||
hooks struct {
|
hooks struct {
|
||||||
Attachment, AuthRoles, AuthTokens, Document, Group, GroupInvitationToken, Item,
|
ActionToken, Attachment, AuthRoles, AuthTokens, Document, Group,
|
||||||
ItemField, Label, Location, MaintenanceEntry, Notifier, User []ent.Hook
|
GroupInvitationToken, Item, ItemField, Label, Location, MaintenanceEntry,
|
||||||
|
Notifier, User []ent.Hook
|
||||||
}
|
}
|
||||||
inters struct {
|
inters struct {
|
||||||
Attachment, AuthRoles, AuthTokens, Document, Group, GroupInvitationToken, Item,
|
ActionToken, Attachment, AuthRoles, AuthTokens, Document, Group,
|
||||||
ItemField, Label, Location, MaintenanceEntry, Notifier, User []ent.Interceptor
|
GroupInvitationToken, Item, ItemField, Label, Location, MaintenanceEntry,
|
||||||
|
Notifier, User []ent.Interceptor
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"entgo.io/ent"
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
|
@ -85,6 +86,7 @@ var (
|
||||||
func checkColumn(table, column string) error {
|
func checkColumn(table, column string) error {
|
||||||
initCheck.Do(func() {
|
initCheck.Do(func() {
|
||||||
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
|
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
|
||||||
|
actiontoken.Table: actiontoken.ValidColumn,
|
||||||
attachment.Table: attachment.ValidColumn,
|
attachment.Table: attachment.ValidColumn,
|
||||||
authroles.Table: authroles.ValidColumn,
|
authroles.Table: authroles.ValidColumn,
|
||||||
authtokens.Table: authtokens.ValidColumn,
|
authtokens.Table: authtokens.ValidColumn,
|
||||||
|
|
|
@ -4,6 +4,10 @@ package ent
|
||||||
|
|
||||||
import "github.com/google/uuid"
|
import "github.com/google/uuid"
|
||||||
|
|
||||||
|
func (at *ActionToken) GetID() uuid.UUID {
|
||||||
|
return at.ID
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Attachment) GetID() uuid.UUID {
|
func (a *Attachment) GetID() uuid.UUID {
|
||||||
return a.ID
|
return a.ID
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,18 @@ import (
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The ActionTokenFunc type is an adapter to allow the use of ordinary
|
||||||
|
// function as ActionToken mutator.
|
||||||
|
type ActionTokenFunc func(context.Context, *ent.ActionTokenMutation) (ent.Value, error)
|
||||||
|
|
||||||
|
// Mutate calls f(ctx, m).
|
||||||
|
func (f ActionTokenFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
|
||||||
|
if mv, ok := m.(*ent.ActionTokenMutation); ok {
|
||||||
|
return f(ctx, mv)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ActionTokenMutation", m)
|
||||||
|
}
|
||||||
|
|
||||||
// The AttachmentFunc type is an adapter to allow the use of ordinary
|
// The AttachmentFunc type is an adapter to allow the use of ordinary
|
||||||
// function as Attachment mutator.
|
// function as Attachment mutator.
|
||||||
type AttachmentFunc func(context.Context, *ent.AttachmentMutation) (ent.Value, error)
|
type AttachmentFunc func(context.Context, *ent.AttachmentMutation) (ent.Value, error)
|
||||||
|
|
|
@ -8,6 +8,46 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// ActionTokensColumns holds the columns for the "action_tokens" table.
|
||||||
|
ActionTokensColumns = []*schema.Column{
|
||||||
|
{Name: "id", Type: field.TypeUUID},
|
||||||
|
{Name: "created_at", Type: field.TypeTime},
|
||||||
|
{Name: "updated_at", Type: field.TypeTime},
|
||||||
|
{Name: "action", Type: field.TypeEnum, Enums: []string{"reset_password"}, Default: "reset_password"},
|
||||||
|
{Name: "token", Type: field.TypeBytes, Unique: true},
|
||||||
|
{Name: "user_id", Type: field.TypeUUID},
|
||||||
|
}
|
||||||
|
// ActionTokensTable holds the schema information for the "action_tokens" table.
|
||||||
|
ActionTokensTable = &schema.Table{
|
||||||
|
Name: "action_tokens",
|
||||||
|
Columns: ActionTokensColumns,
|
||||||
|
PrimaryKey: []*schema.Column{ActionTokensColumns[0]},
|
||||||
|
ForeignKeys: []*schema.ForeignKey{
|
||||||
|
{
|
||||||
|
Symbol: "action_tokens_users_action_tokens",
|
||||||
|
Columns: []*schema.Column{ActionTokensColumns[5]},
|
||||||
|
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||||
|
OnDelete: schema.Cascade,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Indexes: []*schema.Index{
|
||||||
|
{
|
||||||
|
Name: "actiontoken_token",
|
||||||
|
Unique: false,
|
||||||
|
Columns: []*schema.Column{ActionTokensColumns[4]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "actiontoken_action",
|
||||||
|
Unique: false,
|
||||||
|
Columns: []*schema.Column{ActionTokensColumns[3]},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "actiontoken_user_id",
|
||||||
|
Unique: false,
|
||||||
|
Columns: []*schema.Column{ActionTokensColumns[5]},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
// AttachmentsColumns holds the columns for the "attachments" table.
|
// AttachmentsColumns holds the columns for the "attachments" table.
|
||||||
AttachmentsColumns = []*schema.Column{
|
AttachmentsColumns = []*schema.Column{
|
||||||
{Name: "id", Type: field.TypeUUID},
|
{Name: "id", Type: field.TypeUUID},
|
||||||
|
@ -453,6 +493,7 @@ var (
|
||||||
}
|
}
|
||||||
// Tables holds all the tables in the schema.
|
// Tables holds all the tables in the schema.
|
||||||
Tables = []*schema.Table{
|
Tables = []*schema.Table{
|
||||||
|
ActionTokensTable,
|
||||||
AttachmentsTable,
|
AttachmentsTable,
|
||||||
AuthRolesTable,
|
AuthRolesTable,
|
||||||
AuthTokensTable,
|
AuthTokensTable,
|
||||||
|
@ -471,6 +512,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
ActionTokensTable.ForeignKeys[0].RefTable = UsersTable
|
||||||
AttachmentsTable.ForeignKeys[0].RefTable = DocumentsTable
|
AttachmentsTable.ForeignKeys[0].RefTable = DocumentsTable
|
||||||
AttachmentsTable.ForeignKeys[1].RefTable = ItemsTable
|
AttachmentsTable.ForeignKeys[1].RefTable = ItemsTable
|
||||||
AuthRolesTable.ForeignKeys[0].RefTable = AuthTokensTable
|
AuthRolesTable.ForeignKeys[0].RefTable = AuthTokensTable
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"entgo.io/ent"
|
"entgo.io/ent"
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
|
@ -37,6 +38,7 @@ const (
|
||||||
OpUpdateOne = ent.OpUpdateOne
|
OpUpdateOne = ent.OpUpdateOne
|
||||||
|
|
||||||
// Node types.
|
// Node types.
|
||||||
|
TypeActionToken = "ActionToken"
|
||||||
TypeAttachment = "Attachment"
|
TypeAttachment = "Attachment"
|
||||||
TypeAuthRoles = "AuthRoles"
|
TypeAuthRoles = "AuthRoles"
|
||||||
TypeAuthTokens = "AuthTokens"
|
TypeAuthTokens = "AuthTokens"
|
||||||
|
@ -52,6 +54,608 @@ const (
|
||||||
TypeUser = "User"
|
TypeUser = "User"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ActionTokenMutation represents an operation that mutates the ActionToken nodes in the graph.
|
||||||
|
type ActionTokenMutation struct {
|
||||||
|
config
|
||||||
|
op Op
|
||||||
|
typ string
|
||||||
|
id *uuid.UUID
|
||||||
|
created_at *time.Time
|
||||||
|
updated_at *time.Time
|
||||||
|
action *actiontoken.Action
|
||||||
|
token *[]byte
|
||||||
|
clearedFields map[string]struct{}
|
||||||
|
user *uuid.UUID
|
||||||
|
cleareduser bool
|
||||||
|
done bool
|
||||||
|
oldValue func(context.Context) (*ActionToken, error)
|
||||||
|
predicates []predicate.ActionToken
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ ent.Mutation = (*ActionTokenMutation)(nil)
|
||||||
|
|
||||||
|
// actiontokenOption allows management of the mutation configuration using functional options.
|
||||||
|
type actiontokenOption func(*ActionTokenMutation)
|
||||||
|
|
||||||
|
// newActionTokenMutation creates new mutation for the ActionToken entity.
|
||||||
|
func newActionTokenMutation(c config, op Op, opts ...actiontokenOption) *ActionTokenMutation {
|
||||||
|
m := &ActionTokenMutation{
|
||||||
|
config: c,
|
||||||
|
op: op,
|
||||||
|
typ: TypeActionToken,
|
||||||
|
clearedFields: make(map[string]struct{}),
|
||||||
|
}
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(m)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// withActionTokenID sets the ID field of the mutation.
|
||||||
|
func withActionTokenID(id uuid.UUID) actiontokenOption {
|
||||||
|
return func(m *ActionTokenMutation) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
once sync.Once
|
||||||
|
value *ActionToken
|
||||||
|
)
|
||||||
|
m.oldValue = func(ctx context.Context) (*ActionToken, error) {
|
||||||
|
once.Do(func() {
|
||||||
|
if m.done {
|
||||||
|
err = errors.New("querying old values post mutation is not allowed")
|
||||||
|
} else {
|
||||||
|
value, err = m.Client().ActionToken.Get(ctx, id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return value, err
|
||||||
|
}
|
||||||
|
m.id = &id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// withActionToken sets the old ActionToken of the mutation.
|
||||||
|
func withActionToken(node *ActionToken) actiontokenOption {
|
||||||
|
return func(m *ActionTokenMutation) {
|
||||||
|
m.oldValue = func(context.Context) (*ActionToken, error) {
|
||||||
|
return node, nil
|
||||||
|
}
|
||||||
|
m.id = &node.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client returns a new `ent.Client` from the mutation. If the mutation was
|
||||||
|
// executed in a transaction (ent.Tx), a transactional client is returned.
|
||||||
|
func (m ActionTokenMutation) Client() *Client {
|
||||||
|
client := &Client{config: m.config}
|
||||||
|
client.init()
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tx returns an `ent.Tx` for mutations that were executed in transactions;
|
||||||
|
// it returns an error otherwise.
|
||||||
|
func (m ActionTokenMutation) Tx() (*Tx, error) {
|
||||||
|
if _, ok := m.driver.(*txDriver); !ok {
|
||||||
|
return nil, errors.New("ent: mutation is not running in a transaction")
|
||||||
|
}
|
||||||
|
tx := &Tx{config: m.config}
|
||||||
|
tx.init()
|
||||||
|
return tx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetID sets the value of the id field. Note that this
|
||||||
|
// operation is only accepted on creation of ActionToken entities.
|
||||||
|
func (m *ActionTokenMutation) SetID(id uuid.UUID) {
|
||||||
|
m.id = &id
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the ID value in the mutation. Note that the ID is only available
|
||||||
|
// if it was provided to the builder or after it was returned from the database.
|
||||||
|
func (m *ActionTokenMutation) ID() (id uuid.UUID, exists bool) {
|
||||||
|
if m.id == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *m.id, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IDs queries the database and returns the entity ids that match the mutation's predicate.
|
||||||
|
// That means, if the mutation is applied within a transaction with an isolation level such
|
||||||
|
// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated
|
||||||
|
// or updated by the mutation.
|
||||||
|
func (m *ActionTokenMutation) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||||
|
switch {
|
||||||
|
case m.op.Is(OpUpdateOne | OpDeleteOne):
|
||||||
|
id, exists := m.ID()
|
||||||
|
if exists {
|
||||||
|
return []uuid.UUID{id}, nil
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case m.op.Is(OpUpdate | OpDelete):
|
||||||
|
return m.Client().ActionToken.Query().Where(m.predicates...).IDs(ctx)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUserID sets the "user_id" field.
|
||||||
|
func (m *ActionTokenMutation) SetUserID(u uuid.UUID) {
|
||||||
|
m.user = &u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserID returns the value of the "user_id" field in the mutation.
|
||||||
|
func (m *ActionTokenMutation) UserID() (r uuid.UUID, exists bool) {
|
||||||
|
v := m.user
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldUserID returns the old "user_id" field's value of the ActionToken entity.
|
||||||
|
// If the ActionToken object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *ActionTokenMutation) OldUserID(ctx context.Context) (v uuid.UUID, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldUserID is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldUserID requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldUserID: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.UserID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetUserID resets all changes to the "user_id" field.
|
||||||
|
func (m *ActionTokenMutation) ResetUserID() {
|
||||||
|
m.user = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCreatedAt sets the "created_at" field.
|
||||||
|
func (m *ActionTokenMutation) SetCreatedAt(t time.Time) {
|
||||||
|
m.created_at = &t
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatedAt returns the value of the "created_at" field in the mutation.
|
||||||
|
func (m *ActionTokenMutation) CreatedAt() (r time.Time, exists bool) {
|
||||||
|
v := m.created_at
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldCreatedAt returns the old "created_at" field's value of the ActionToken entity.
|
||||||
|
// If the ActionToken object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *ActionTokenMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldCreatedAt requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.CreatedAt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetCreatedAt resets all changes to the "created_at" field.
|
||||||
|
func (m *ActionTokenMutation) ResetCreatedAt() {
|
||||||
|
m.created_at = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUpdatedAt sets the "updated_at" field.
|
||||||
|
func (m *ActionTokenMutation) SetUpdatedAt(t time.Time) {
|
||||||
|
m.updated_at = &t
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdatedAt returns the value of the "updated_at" field in the mutation.
|
||||||
|
func (m *ActionTokenMutation) UpdatedAt() (r time.Time, exists bool) {
|
||||||
|
v := m.updated_at
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldUpdatedAt returns the old "updated_at" field's value of the ActionToken entity.
|
||||||
|
// If the ActionToken object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *ActionTokenMutation) OldUpdatedAt(ctx context.Context) (v time.Time, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldUpdatedAt is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldUpdatedAt requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldUpdatedAt: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.UpdatedAt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetUpdatedAt resets all changes to the "updated_at" field.
|
||||||
|
func (m *ActionTokenMutation) ResetUpdatedAt() {
|
||||||
|
m.updated_at = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAction sets the "action" field.
|
||||||
|
func (m *ActionTokenMutation) SetAction(a actiontoken.Action) {
|
||||||
|
m.action = &a
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action returns the value of the "action" field in the mutation.
|
||||||
|
func (m *ActionTokenMutation) Action() (r actiontoken.Action, exists bool) {
|
||||||
|
v := m.action
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldAction returns the old "action" field's value of the ActionToken entity.
|
||||||
|
// If the ActionToken object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *ActionTokenMutation) OldAction(ctx context.Context) (v actiontoken.Action, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldAction is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldAction requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldAction: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.Action, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetAction resets all changes to the "action" field.
|
||||||
|
func (m *ActionTokenMutation) ResetAction() {
|
||||||
|
m.action = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetToken sets the "token" field.
|
||||||
|
func (m *ActionTokenMutation) SetToken(b []byte) {
|
||||||
|
m.token = &b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token returns the value of the "token" field in the mutation.
|
||||||
|
func (m *ActionTokenMutation) Token() (r []byte, exists bool) {
|
||||||
|
v := m.token
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldToken returns the old "token" field's value of the ActionToken entity.
|
||||||
|
// If the ActionToken object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *ActionTokenMutation) OldToken(ctx context.Context) (v []byte, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldToken is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldToken requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldToken: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.Token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetToken resets all changes to the "token" field.
|
||||||
|
func (m *ActionTokenMutation) ResetToken() {
|
||||||
|
m.token = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearUser clears the "user" edge to the User entity.
|
||||||
|
func (m *ActionTokenMutation) ClearUser() {
|
||||||
|
m.cleareduser = true
|
||||||
|
m.clearedFields[actiontoken.FieldUserID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserCleared reports if the "user" edge to the User entity was cleared.
|
||||||
|
func (m *ActionTokenMutation) UserCleared() bool {
|
||||||
|
return m.cleareduser
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserIDs returns the "user" edge IDs in the mutation.
|
||||||
|
// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use
|
||||||
|
// UserID instead. It exists only for internal usage by the builders.
|
||||||
|
func (m *ActionTokenMutation) UserIDs() (ids []uuid.UUID) {
|
||||||
|
if id := m.user; id != nil {
|
||||||
|
ids = append(ids, *id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetUser resets all changes to the "user" edge.
|
||||||
|
func (m *ActionTokenMutation) ResetUser() {
|
||||||
|
m.user = nil
|
||||||
|
m.cleareduser = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Where appends a list predicates to the ActionTokenMutation builder.
|
||||||
|
func (m *ActionTokenMutation) Where(ps ...predicate.ActionToken) {
|
||||||
|
m.predicates = append(m.predicates, ps...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WhereP appends storage-level predicates to the ActionTokenMutation builder. Using this method,
|
||||||
|
// users can use type-assertion to append predicates that do not depend on any generated package.
|
||||||
|
func (m *ActionTokenMutation) WhereP(ps ...func(*sql.Selector)) {
|
||||||
|
p := make([]predicate.ActionToken, len(ps))
|
||||||
|
for i := range ps {
|
||||||
|
p[i] = ps[i]
|
||||||
|
}
|
||||||
|
m.Where(p...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Op returns the operation name.
|
||||||
|
func (m *ActionTokenMutation) Op() Op {
|
||||||
|
return m.op
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOp allows setting the mutation operation.
|
||||||
|
func (m *ActionTokenMutation) SetOp(op Op) {
|
||||||
|
m.op = op
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type returns the node type of this mutation (ActionToken).
|
||||||
|
func (m *ActionTokenMutation) Type() string {
|
||||||
|
return m.typ
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields returns all fields that were changed during this mutation. Note that in
|
||||||
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
|
// AddedFields().
|
||||||
|
func (m *ActionTokenMutation) Fields() []string {
|
||||||
|
fields := make([]string, 0, 5)
|
||||||
|
if m.user != nil {
|
||||||
|
fields = append(fields, actiontoken.FieldUserID)
|
||||||
|
}
|
||||||
|
if m.created_at != nil {
|
||||||
|
fields = append(fields, actiontoken.FieldCreatedAt)
|
||||||
|
}
|
||||||
|
if m.updated_at != nil {
|
||||||
|
fields = append(fields, actiontoken.FieldUpdatedAt)
|
||||||
|
}
|
||||||
|
if m.action != nil {
|
||||||
|
fields = append(fields, actiontoken.FieldAction)
|
||||||
|
}
|
||||||
|
if m.token != nil {
|
||||||
|
fields = append(fields, actiontoken.FieldToken)
|
||||||
|
}
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field returns the value of a field with the given name. The second boolean
|
||||||
|
// return value indicates that this field was not set, or was not defined in the
|
||||||
|
// schema.
|
||||||
|
func (m *ActionTokenMutation) Field(name string) (ent.Value, bool) {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.FieldUserID:
|
||||||
|
return m.UserID()
|
||||||
|
case actiontoken.FieldCreatedAt:
|
||||||
|
return m.CreatedAt()
|
||||||
|
case actiontoken.FieldUpdatedAt:
|
||||||
|
return m.UpdatedAt()
|
||||||
|
case actiontoken.FieldAction:
|
||||||
|
return m.Action()
|
||||||
|
case actiontoken.FieldToken:
|
||||||
|
return m.Token()
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldField returns the old value of the field from the database. An error is
|
||||||
|
// returned if the mutation operation is not UpdateOne, or the query to the
|
||||||
|
// database failed.
|
||||||
|
func (m *ActionTokenMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.FieldUserID:
|
||||||
|
return m.OldUserID(ctx)
|
||||||
|
case actiontoken.FieldCreatedAt:
|
||||||
|
return m.OldCreatedAt(ctx)
|
||||||
|
case actiontoken.FieldUpdatedAt:
|
||||||
|
return m.OldUpdatedAt(ctx)
|
||||||
|
case actiontoken.FieldAction:
|
||||||
|
return m.OldAction(ctx)
|
||||||
|
case actiontoken.FieldToken:
|
||||||
|
return m.OldToken(ctx)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unknown ActionToken field %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetField sets the value of a field with the given name. It returns an error if
|
||||||
|
// the field is not defined in the schema, or if the type mismatched the field
|
||||||
|
// type.
|
||||||
|
func (m *ActionTokenMutation) SetField(name string, value ent.Value) error {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.FieldUserID:
|
||||||
|
v, ok := value.(uuid.UUID)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetUserID(v)
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldCreatedAt:
|
||||||
|
v, ok := value.(time.Time)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetCreatedAt(v)
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldUpdatedAt:
|
||||||
|
v, ok := value.(time.Time)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetUpdatedAt(v)
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldAction:
|
||||||
|
v, ok := value.(actiontoken.Action)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetAction(v)
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldToken:
|
||||||
|
v, ok := value.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetToken(v)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unknown ActionToken field %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedFields returns all numeric fields that were incremented/decremented during
|
||||||
|
// this mutation.
|
||||||
|
func (m *ActionTokenMutation) AddedFields() []string {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedField returns the numeric value that was incremented/decremented on a field
|
||||||
|
// with the given name. The second boolean return value indicates that this field
|
||||||
|
// was not set, or was not defined in the schema.
|
||||||
|
func (m *ActionTokenMutation) AddedField(name string) (ent.Value, bool) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddField adds the value to the field with the given name. It returns an error if
|
||||||
|
// the field is not defined in the schema, or if the type mismatched the field
|
||||||
|
// type.
|
||||||
|
func (m *ActionTokenMutation) AddField(name string, value ent.Value) error {
|
||||||
|
switch name {
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unknown ActionToken numeric field %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearedFields returns all nullable fields that were cleared during this
|
||||||
|
// mutation.
|
||||||
|
func (m *ActionTokenMutation) ClearedFields() []string {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FieldCleared returns a boolean indicating if a field with the given name was
|
||||||
|
// cleared in this mutation.
|
||||||
|
func (m *ActionTokenMutation) FieldCleared(name string) bool {
|
||||||
|
_, ok := m.clearedFields[name]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearField clears the value of the field with the given name. It returns an
|
||||||
|
// error if the field is not defined in the schema.
|
||||||
|
func (m *ActionTokenMutation) ClearField(name string) error {
|
||||||
|
return fmt.Errorf("unknown ActionToken nullable field %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetField resets all changes in the mutation for the field with the given name.
|
||||||
|
// It returns an error if the field is not defined in the schema.
|
||||||
|
func (m *ActionTokenMutation) ResetField(name string) error {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.FieldUserID:
|
||||||
|
m.ResetUserID()
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldCreatedAt:
|
||||||
|
m.ResetCreatedAt()
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldUpdatedAt:
|
||||||
|
m.ResetUpdatedAt()
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldAction:
|
||||||
|
m.ResetAction()
|
||||||
|
return nil
|
||||||
|
case actiontoken.FieldToken:
|
||||||
|
m.ResetToken()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unknown ActionToken field %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedEdges returns all edge names that were set/added in this mutation.
|
||||||
|
func (m *ActionTokenMutation) AddedEdges() []string {
|
||||||
|
edges := make([]string, 0, 1)
|
||||||
|
if m.user != nil {
|
||||||
|
edges = append(edges, actiontoken.EdgeUser)
|
||||||
|
}
|
||||||
|
return edges
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedIDs returns all IDs (to other nodes) that were added for the given edge
|
||||||
|
// name in this mutation.
|
||||||
|
func (m *ActionTokenMutation) AddedIDs(name string) []ent.Value {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.EdgeUser:
|
||||||
|
if id := m.user; id != nil {
|
||||||
|
return []ent.Value{*id}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovedEdges returns all edge names that were removed in this mutation.
|
||||||
|
func (m *ActionTokenMutation) RemovedEdges() []string {
|
||||||
|
edges := make([]string, 0, 1)
|
||||||
|
return edges
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with
|
||||||
|
// the given name in this mutation.
|
||||||
|
func (m *ActionTokenMutation) RemovedIDs(name string) []ent.Value {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearedEdges returns all edge names that were cleared in this mutation.
|
||||||
|
func (m *ActionTokenMutation) ClearedEdges() []string {
|
||||||
|
edges := make([]string, 0, 1)
|
||||||
|
if m.cleareduser {
|
||||||
|
edges = append(edges, actiontoken.EdgeUser)
|
||||||
|
}
|
||||||
|
return edges
|
||||||
|
}
|
||||||
|
|
||||||
|
// EdgeCleared returns a boolean which indicates if the edge with the given name
|
||||||
|
// was cleared in this mutation.
|
||||||
|
func (m *ActionTokenMutation) EdgeCleared(name string) bool {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.EdgeUser:
|
||||||
|
return m.cleareduser
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearEdge clears the value of the edge with the given name. It returns an error
|
||||||
|
// if that edge is not defined in the schema.
|
||||||
|
func (m *ActionTokenMutation) ClearEdge(name string) error {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.EdgeUser:
|
||||||
|
m.ClearUser()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unknown ActionToken unique edge %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetEdge resets all changes to the edge with the given name in this mutation.
|
||||||
|
// It returns an error if the edge is not defined in the schema.
|
||||||
|
func (m *ActionTokenMutation) ResetEdge(name string) error {
|
||||||
|
switch name {
|
||||||
|
case actiontoken.EdgeUser:
|
||||||
|
m.ResetUser()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("unknown ActionToken edge %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
// AttachmentMutation represents an operation that mutates the Attachment nodes in the graph.
|
// AttachmentMutation represents an operation that mutates the Attachment nodes in the graph.
|
||||||
type AttachmentMutation struct {
|
type AttachmentMutation struct {
|
||||||
config
|
config
|
||||||
|
@ -10672,30 +11276,33 @@ func (m *NotifierMutation) ResetEdge(name string) error {
|
||||||
// UserMutation represents an operation that mutates the User nodes in the graph.
|
// UserMutation represents an operation that mutates the User nodes in the graph.
|
||||||
type UserMutation struct {
|
type UserMutation struct {
|
||||||
config
|
config
|
||||||
op Op
|
op Op
|
||||||
typ string
|
typ string
|
||||||
id *uuid.UUID
|
id *uuid.UUID
|
||||||
created_at *time.Time
|
created_at *time.Time
|
||||||
updated_at *time.Time
|
updated_at *time.Time
|
||||||
name *string
|
name *string
|
||||||
email *string
|
email *string
|
||||||
password *string
|
password *string
|
||||||
is_superuser *bool
|
is_superuser *bool
|
||||||
superuser *bool
|
superuser *bool
|
||||||
role *user.Role
|
role *user.Role
|
||||||
activated_on *time.Time
|
activated_on *time.Time
|
||||||
clearedFields map[string]struct{}
|
clearedFields map[string]struct{}
|
||||||
group *uuid.UUID
|
group *uuid.UUID
|
||||||
clearedgroup bool
|
clearedgroup bool
|
||||||
auth_tokens map[uuid.UUID]struct{}
|
auth_tokens map[uuid.UUID]struct{}
|
||||||
removedauth_tokens map[uuid.UUID]struct{}
|
removedauth_tokens map[uuid.UUID]struct{}
|
||||||
clearedauth_tokens bool
|
clearedauth_tokens bool
|
||||||
notifiers map[uuid.UUID]struct{}
|
notifiers map[uuid.UUID]struct{}
|
||||||
removednotifiers map[uuid.UUID]struct{}
|
removednotifiers map[uuid.UUID]struct{}
|
||||||
clearednotifiers bool
|
clearednotifiers bool
|
||||||
done bool
|
action_tokens map[uuid.UUID]struct{}
|
||||||
oldValue func(context.Context) (*User, error)
|
removedaction_tokens map[uuid.UUID]struct{}
|
||||||
predicates []predicate.User
|
clearedaction_tokens bool
|
||||||
|
done bool
|
||||||
|
oldValue func(context.Context) (*User, error)
|
||||||
|
predicates []predicate.User
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ ent.Mutation = (*UserMutation)(nil)
|
var _ ent.Mutation = (*UserMutation)(nil)
|
||||||
|
@ -11286,6 +11893,60 @@ func (m *UserMutation) ResetNotifiers() {
|
||||||
m.removednotifiers = nil
|
m.removednotifiers = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddActionTokenIDs adds the "action_tokens" edge to the ActionToken entity by ids.
|
||||||
|
func (m *UserMutation) AddActionTokenIDs(ids ...uuid.UUID) {
|
||||||
|
if m.action_tokens == nil {
|
||||||
|
m.action_tokens = make(map[uuid.UUID]struct{})
|
||||||
|
}
|
||||||
|
for i := range ids {
|
||||||
|
m.action_tokens[ids[i]] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearActionTokens clears the "action_tokens" edge to the ActionToken entity.
|
||||||
|
func (m *UserMutation) ClearActionTokens() {
|
||||||
|
m.clearedaction_tokens = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokensCleared reports if the "action_tokens" edge to the ActionToken entity was cleared.
|
||||||
|
func (m *UserMutation) ActionTokensCleared() bool {
|
||||||
|
return m.clearedaction_tokens
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveActionTokenIDs removes the "action_tokens" edge to the ActionToken entity by IDs.
|
||||||
|
func (m *UserMutation) RemoveActionTokenIDs(ids ...uuid.UUID) {
|
||||||
|
if m.removedaction_tokens == nil {
|
||||||
|
m.removedaction_tokens = make(map[uuid.UUID]struct{})
|
||||||
|
}
|
||||||
|
for i := range ids {
|
||||||
|
delete(m.action_tokens, ids[i])
|
||||||
|
m.removedaction_tokens[ids[i]] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovedActionTokens returns the removed IDs of the "action_tokens" edge to the ActionToken entity.
|
||||||
|
func (m *UserMutation) RemovedActionTokensIDs() (ids []uuid.UUID) {
|
||||||
|
for id := range m.removedaction_tokens {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionTokensIDs returns the "action_tokens" edge IDs in the mutation.
|
||||||
|
func (m *UserMutation) ActionTokensIDs() (ids []uuid.UUID) {
|
||||||
|
for id := range m.action_tokens {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetActionTokens resets all changes to the "action_tokens" edge.
|
||||||
|
func (m *UserMutation) ResetActionTokens() {
|
||||||
|
m.action_tokens = nil
|
||||||
|
m.clearedaction_tokens = false
|
||||||
|
m.removedaction_tokens = nil
|
||||||
|
}
|
||||||
|
|
||||||
// Where appends a list predicates to the UserMutation builder.
|
// Where appends a list predicates to the UserMutation builder.
|
||||||
func (m *UserMutation) Where(ps ...predicate.User) {
|
func (m *UserMutation) Where(ps ...predicate.User) {
|
||||||
m.predicates = append(m.predicates, ps...)
|
m.predicates = append(m.predicates, ps...)
|
||||||
|
@ -11564,7 +12225,7 @@ func (m *UserMutation) ResetField(name string) error {
|
||||||
|
|
||||||
// AddedEdges returns all edge names that were set/added in this mutation.
|
// AddedEdges returns all edge names that were set/added in this mutation.
|
||||||
func (m *UserMutation) AddedEdges() []string {
|
func (m *UserMutation) AddedEdges() []string {
|
||||||
edges := make([]string, 0, 3)
|
edges := make([]string, 0, 4)
|
||||||
if m.group != nil {
|
if m.group != nil {
|
||||||
edges = append(edges, user.EdgeGroup)
|
edges = append(edges, user.EdgeGroup)
|
||||||
}
|
}
|
||||||
|
@ -11574,6 +12235,9 @@ func (m *UserMutation) AddedEdges() []string {
|
||||||
if m.notifiers != nil {
|
if m.notifiers != nil {
|
||||||
edges = append(edges, user.EdgeNotifiers)
|
edges = append(edges, user.EdgeNotifiers)
|
||||||
}
|
}
|
||||||
|
if m.action_tokens != nil {
|
||||||
|
edges = append(edges, user.EdgeActionTokens)
|
||||||
|
}
|
||||||
return edges
|
return edges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11597,19 +12261,28 @@ func (m *UserMutation) AddedIDs(name string) []ent.Value {
|
||||||
ids = append(ids, id)
|
ids = append(ids, id)
|
||||||
}
|
}
|
||||||
return ids
|
return ids
|
||||||
|
case user.EdgeActionTokens:
|
||||||
|
ids := make([]ent.Value, 0, len(m.action_tokens))
|
||||||
|
for id := range m.action_tokens {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
return ids
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemovedEdges returns all edge names that were removed in this mutation.
|
// RemovedEdges returns all edge names that were removed in this mutation.
|
||||||
func (m *UserMutation) RemovedEdges() []string {
|
func (m *UserMutation) RemovedEdges() []string {
|
||||||
edges := make([]string, 0, 3)
|
edges := make([]string, 0, 4)
|
||||||
if m.removedauth_tokens != nil {
|
if m.removedauth_tokens != nil {
|
||||||
edges = append(edges, user.EdgeAuthTokens)
|
edges = append(edges, user.EdgeAuthTokens)
|
||||||
}
|
}
|
||||||
if m.removednotifiers != nil {
|
if m.removednotifiers != nil {
|
||||||
edges = append(edges, user.EdgeNotifiers)
|
edges = append(edges, user.EdgeNotifiers)
|
||||||
}
|
}
|
||||||
|
if m.removedaction_tokens != nil {
|
||||||
|
edges = append(edges, user.EdgeActionTokens)
|
||||||
|
}
|
||||||
return edges
|
return edges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11629,13 +12302,19 @@ func (m *UserMutation) RemovedIDs(name string) []ent.Value {
|
||||||
ids = append(ids, id)
|
ids = append(ids, id)
|
||||||
}
|
}
|
||||||
return ids
|
return ids
|
||||||
|
case user.EdgeActionTokens:
|
||||||
|
ids := make([]ent.Value, 0, len(m.removedaction_tokens))
|
||||||
|
for id := range m.removedaction_tokens {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
return ids
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearedEdges returns all edge names that were cleared in this mutation.
|
// ClearedEdges returns all edge names that were cleared in this mutation.
|
||||||
func (m *UserMutation) ClearedEdges() []string {
|
func (m *UserMutation) ClearedEdges() []string {
|
||||||
edges := make([]string, 0, 3)
|
edges := make([]string, 0, 4)
|
||||||
if m.clearedgroup {
|
if m.clearedgroup {
|
||||||
edges = append(edges, user.EdgeGroup)
|
edges = append(edges, user.EdgeGroup)
|
||||||
}
|
}
|
||||||
|
@ -11645,6 +12324,9 @@ func (m *UserMutation) ClearedEdges() []string {
|
||||||
if m.clearednotifiers {
|
if m.clearednotifiers {
|
||||||
edges = append(edges, user.EdgeNotifiers)
|
edges = append(edges, user.EdgeNotifiers)
|
||||||
}
|
}
|
||||||
|
if m.clearedaction_tokens {
|
||||||
|
edges = append(edges, user.EdgeActionTokens)
|
||||||
|
}
|
||||||
return edges
|
return edges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11658,6 +12340,8 @@ func (m *UserMutation) EdgeCleared(name string) bool {
|
||||||
return m.clearedauth_tokens
|
return m.clearedauth_tokens
|
||||||
case user.EdgeNotifiers:
|
case user.EdgeNotifiers:
|
||||||
return m.clearednotifiers
|
return m.clearednotifiers
|
||||||
|
case user.EdgeActionTokens:
|
||||||
|
return m.clearedaction_tokens
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -11686,6 +12370,9 @@ func (m *UserMutation) ResetEdge(name string) error {
|
||||||
case user.EdgeNotifiers:
|
case user.EdgeNotifiers:
|
||||||
m.ResetNotifiers()
|
m.ResetNotifiers()
|
||||||
return nil
|
return nil
|
||||||
|
case user.EdgeActionTokens:
|
||||||
|
m.ResetActionTokens()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown User edge %s", name)
|
return fmt.Errorf("unknown User edge %s", name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,9 @@ import (
|
||||||
"entgo.io/ent/dialect/sql"
|
"entgo.io/ent/dialect/sql"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ActionToken is the predicate function for actiontoken builders.
|
||||||
|
type ActionToken func(*sql.Selector)
|
||||||
|
|
||||||
// Attachment is the predicate function for attachment builders.
|
// Attachment is the predicate function for attachment builders.
|
||||||
type Attachment func(*sql.Selector)
|
type Attachment func(*sql.Selector)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||||
|
@ -25,6 +26,25 @@ import (
|
||||||
// (default values, validators, hooks and policies) and stitches it
|
// (default values, validators, hooks and policies) and stitches it
|
||||||
// to their package variables.
|
// to their package variables.
|
||||||
func init() {
|
func init() {
|
||||||
|
actiontokenMixin := schema.ActionToken{}.Mixin()
|
||||||
|
actiontokenMixinFields1 := actiontokenMixin[1].Fields()
|
||||||
|
_ = actiontokenMixinFields1
|
||||||
|
actiontokenFields := schema.ActionToken{}.Fields()
|
||||||
|
_ = actiontokenFields
|
||||||
|
// actiontokenDescCreatedAt is the schema descriptor for created_at field.
|
||||||
|
actiontokenDescCreatedAt := actiontokenMixinFields1[1].Descriptor()
|
||||||
|
// actiontoken.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||||
|
actiontoken.DefaultCreatedAt = actiontokenDescCreatedAt.Default.(func() time.Time)
|
||||||
|
// actiontokenDescUpdatedAt is the schema descriptor for updated_at field.
|
||||||
|
actiontokenDescUpdatedAt := actiontokenMixinFields1[2].Descriptor()
|
||||||
|
// actiontoken.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||||
|
actiontoken.DefaultUpdatedAt = actiontokenDescUpdatedAt.Default.(func() time.Time)
|
||||||
|
// actiontoken.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||||
|
actiontoken.UpdateDefaultUpdatedAt = actiontokenDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||||
|
// actiontokenDescID is the schema descriptor for id field.
|
||||||
|
actiontokenDescID := actiontokenMixinFields1[0].Descriptor()
|
||||||
|
// actiontoken.DefaultID holds the default value on creation for the id field.
|
||||||
|
actiontoken.DefaultID = actiontokenDescID.Default.(func() uuid.UUID)
|
||||||
attachmentMixin := schema.Attachment{}.Mixin()
|
attachmentMixin := schema.Attachment{}.Mixin()
|
||||||
attachmentMixinFields0 := attachmentMixin[0].Fields()
|
attachmentMixinFields0 := attachmentMixin[0].Fields()
|
||||||
_ = attachmentMixinFields0
|
_ = attachmentMixinFields0
|
||||||
|
|
42
backend/internal/data/ent/schema/actiontoken.go
Normal file
42
backend/internal/data/ent/schema/actiontoken.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package schema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"entgo.io/ent"
|
||||||
|
"entgo.io/ent/schema/field"
|
||||||
|
"entgo.io/ent/schema/index"
|
||||||
|
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ActionToken struct {
|
||||||
|
ent.Schema
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ActionToken) Mixin() []ent.Mixin {
|
||||||
|
return []ent.Mixin{
|
||||||
|
UserMixin{
|
||||||
|
ref: "action_tokens",
|
||||||
|
field: "user_id",
|
||||||
|
},
|
||||||
|
mixins.BaseMixin{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fields of the ActionToken.
|
||||||
|
func (ActionToken) Fields() []ent.Field {
|
||||||
|
return []ent.Field{
|
||||||
|
field.Enum("action").
|
||||||
|
Values("reset_password").
|
||||||
|
Default("reset_password"),
|
||||||
|
field.Bytes("token").
|
||||||
|
Unique(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ActionToken) Indexes() []ent.Index {
|
||||||
|
return []ent.Index{
|
||||||
|
index.Fields("token"),
|
||||||
|
index.Fields("action"),
|
||||||
|
index.Fields("user_id"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,13 +52,11 @@ func (User) Fields() []ent.Field {
|
||||||
func (User) Edges() []ent.Edge {
|
func (User) Edges() []ent.Edge {
|
||||||
return []ent.Edge{
|
return []ent.Edge{
|
||||||
edge.To("auth_tokens", AuthTokens.Type).
|
edge.To("auth_tokens", AuthTokens.Type).
|
||||||
Annotations(entsql.Annotation{
|
Annotations(entsql.Annotation{OnDelete: entsql.Cascade}),
|
||||||
OnDelete: entsql.Cascade,
|
|
||||||
}),
|
|
||||||
edge.To("notifiers", Notifier.Type).
|
edge.To("notifiers", Notifier.Type).
|
||||||
Annotations(entsql.Annotation{
|
Annotations(entsql.Annotation{OnDelete: entsql.Cascade}),
|
||||||
OnDelete: entsql.Cascade,
|
edge.To("action_tokens", ActionToken.Type).
|
||||||
}),
|
Annotations(entsql.Annotation{OnDelete: entsql.Cascade}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
// Tx is a transactional client that is created by calling Client.Tx().
|
// Tx is a transactional client that is created by calling Client.Tx().
|
||||||
type Tx struct {
|
type Tx struct {
|
||||||
config
|
config
|
||||||
|
// ActionToken is the client for interacting with the ActionToken builders.
|
||||||
|
ActionToken *ActionTokenClient
|
||||||
// Attachment is the client for interacting with the Attachment builders.
|
// Attachment is the client for interacting with the Attachment builders.
|
||||||
Attachment *AttachmentClient
|
Attachment *AttachmentClient
|
||||||
// AuthRoles is the client for interacting with the AuthRoles builders.
|
// AuthRoles is the client for interacting with the AuthRoles builders.
|
||||||
|
@ -169,6 +171,7 @@ func (tx *Tx) Client() *Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Tx) init() {
|
func (tx *Tx) init() {
|
||||||
|
tx.ActionToken = NewActionTokenClient(tx.config)
|
||||||
tx.Attachment = NewAttachmentClient(tx.config)
|
tx.Attachment = NewAttachmentClient(tx.config)
|
||||||
tx.AuthRoles = NewAuthRolesClient(tx.config)
|
tx.AuthRoles = NewAuthRolesClient(tx.config)
|
||||||
tx.AuthTokens = NewAuthTokensClient(tx.config)
|
tx.AuthTokens = NewAuthTokensClient(tx.config)
|
||||||
|
@ -191,7 +194,7 @@ func (tx *Tx) init() {
|
||||||
// of them in order to commit or rollback the transaction.
|
// of them in order to commit or rollback the transaction.
|
||||||
//
|
//
|
||||||
// If a closed transaction is embedded in one of the generated entities, and the entity
|
// If a closed transaction is embedded in one of the generated entities, and the entity
|
||||||
// applies a query, for example: Attachment.QueryXXX(), the query will be executed
|
// applies a query, for example: ActionToken.QueryXXX(), the query will be executed
|
||||||
// through the driver which created this transaction.
|
// through the driver which created this transaction.
|
||||||
//
|
//
|
||||||
// Note that txDriver is not goroutine safe.
|
// Note that txDriver is not goroutine safe.
|
||||||
|
|
|
@ -52,9 +52,11 @@ type UserEdges struct {
|
||||||
AuthTokens []*AuthTokens `json:"auth_tokens,omitempty"`
|
AuthTokens []*AuthTokens `json:"auth_tokens,omitempty"`
|
||||||
// Notifiers holds the value of the notifiers edge.
|
// Notifiers holds the value of the notifiers edge.
|
||||||
Notifiers []*Notifier `json:"notifiers,omitempty"`
|
Notifiers []*Notifier `json:"notifiers,omitempty"`
|
||||||
|
// ActionTokens holds the value of the action_tokens edge.
|
||||||
|
ActionTokens []*ActionToken `json:"action_tokens,omitempty"`
|
||||||
// loadedTypes holds the information for reporting if a
|
// loadedTypes holds the information for reporting if a
|
||||||
// type was loaded (or requested) in eager-loading or not.
|
// type was loaded (or requested) in eager-loading or not.
|
||||||
loadedTypes [3]bool
|
loadedTypes [4]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// GroupOrErr returns the Group value or an error if the edge
|
// GroupOrErr returns the Group value or an error if the edge
|
||||||
|
@ -88,6 +90,15 @@ func (e UserEdges) NotifiersOrErr() ([]*Notifier, error) {
|
||||||
return nil, &NotLoadedError{edge: "notifiers"}
|
return nil, &NotLoadedError{edge: "notifiers"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionTokensOrErr returns the ActionTokens value or an error if the edge
|
||||||
|
// was not loaded in eager-loading.
|
||||||
|
func (e UserEdges) ActionTokensOrErr() ([]*ActionToken, error) {
|
||||||
|
if e.loadedTypes[3] {
|
||||||
|
return e.ActionTokens, nil
|
||||||
|
}
|
||||||
|
return nil, &NotLoadedError{edge: "action_tokens"}
|
||||||
|
}
|
||||||
|
|
||||||
// scanValues returns the types for scanning values from sql.Rows.
|
// scanValues returns the types for scanning values from sql.Rows.
|
||||||
func (*User) scanValues(columns []string) ([]any, error) {
|
func (*User) scanValues(columns []string) ([]any, error) {
|
||||||
values := make([]any, len(columns))
|
values := make([]any, len(columns))
|
||||||
|
@ -213,6 +224,11 @@ func (u *User) QueryNotifiers() *NotifierQuery {
|
||||||
return NewUserClient(u.config).QueryNotifiers(u)
|
return NewUserClient(u.config).QueryNotifiers(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryActionTokens queries the "action_tokens" edge of the User entity.
|
||||||
|
func (u *User) QueryActionTokens() *ActionTokenQuery {
|
||||||
|
return NewUserClient(u.config).QueryActionTokens(u)
|
||||||
|
}
|
||||||
|
|
||||||
// Update returns a builder for updating this User.
|
// Update returns a builder for updating this User.
|
||||||
// Note that you need to call User.Unwrap() before calling this method if this User
|
// Note that you need to call User.Unwrap() before calling this method if this User
|
||||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||||
|
|
|
@ -40,6 +40,8 @@ const (
|
||||||
EdgeAuthTokens = "auth_tokens"
|
EdgeAuthTokens = "auth_tokens"
|
||||||
// EdgeNotifiers holds the string denoting the notifiers edge name in mutations.
|
// EdgeNotifiers holds the string denoting the notifiers edge name in mutations.
|
||||||
EdgeNotifiers = "notifiers"
|
EdgeNotifiers = "notifiers"
|
||||||
|
// EdgeActionTokens holds the string denoting the action_tokens edge name in mutations.
|
||||||
|
EdgeActionTokens = "action_tokens"
|
||||||
// Table holds the table name of the user in the database.
|
// Table holds the table name of the user in the database.
|
||||||
Table = "users"
|
Table = "users"
|
||||||
// GroupTable is the table that holds the group relation/edge.
|
// GroupTable is the table that holds the group relation/edge.
|
||||||
|
@ -63,6 +65,13 @@ const (
|
||||||
NotifiersInverseTable = "notifiers"
|
NotifiersInverseTable = "notifiers"
|
||||||
// NotifiersColumn is the table column denoting the notifiers relation/edge.
|
// NotifiersColumn is the table column denoting the notifiers relation/edge.
|
||||||
NotifiersColumn = "user_id"
|
NotifiersColumn = "user_id"
|
||||||
|
// ActionTokensTable is the table that holds the action_tokens relation/edge.
|
||||||
|
ActionTokensTable = "action_tokens"
|
||||||
|
// ActionTokensInverseTable is the table name for the ActionToken entity.
|
||||||
|
// It exists in this package in order to avoid circular dependency with the "actiontoken" package.
|
||||||
|
ActionTokensInverseTable = "action_tokens"
|
||||||
|
// ActionTokensColumn is the table column denoting the action_tokens relation/edge.
|
||||||
|
ActionTokensColumn = "user_id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Columns holds all SQL columns for user fields.
|
// Columns holds all SQL columns for user fields.
|
||||||
|
@ -234,6 +243,20 @@ func ByNotifiers(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
sqlgraph.OrderByNeighborTerms(s, newNotifiersStep(), append([]sql.OrderTerm{term}, terms...)...)
|
sqlgraph.OrderByNeighborTerms(s, newNotifiersStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByActionTokensCount orders the results by action_tokens count.
|
||||||
|
func ByActionTokensCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborsCount(s, newActionTokensStep(), opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByActionTokens orders the results by action_tokens terms.
|
||||||
|
func ByActionTokens(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||||
|
return func(s *sql.Selector) {
|
||||||
|
sqlgraph.OrderByNeighborTerms(s, newActionTokensStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
func newGroupStep() *sqlgraph.Step {
|
func newGroupStep() *sqlgraph.Step {
|
||||||
return sqlgraph.NewStep(
|
return sqlgraph.NewStep(
|
||||||
sqlgraph.From(Table, FieldID),
|
sqlgraph.From(Table, FieldID),
|
||||||
|
@ -255,3 +278,10 @@ func newNotifiersStep() *sqlgraph.Step {
|
||||||
sqlgraph.Edge(sqlgraph.O2M, false, NotifiersTable, NotifiersColumn),
|
sqlgraph.Edge(sqlgraph.O2M, false, NotifiersTable, NotifiersColumn),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
func newActionTokensStep() *sqlgraph.Step {
|
||||||
|
return sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.To(ActionTokensInverseTable, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, ActionTokensTable, ActionTokensColumn),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -530,6 +530,29 @@ func HasNotifiersWith(preds ...predicate.Notifier) predicate.User {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasActionTokens applies the HasEdge predicate on the "action_tokens" edge.
|
||||||
|
func HasActionTokens() predicate.User {
|
||||||
|
return predicate.User(func(s *sql.Selector) {
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(Table, FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, ActionTokensTable, ActionTokensColumn),
|
||||||
|
)
|
||||||
|
sqlgraph.HasNeighbors(s, step)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasActionTokensWith applies the HasEdge predicate on the "action_tokens" edge with a given conditions (other predicates).
|
||||||
|
func HasActionTokensWith(preds ...predicate.ActionToken) predicate.User {
|
||||||
|
return predicate.User(func(s *sql.Selector) {
|
||||||
|
step := newActionTokensStep()
|
||||||
|
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||||
|
for _, p := range preds {
|
||||||
|
p(s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// And groups predicates with the AND operator between them.
|
// And groups predicates with the AND operator between them.
|
||||||
func And(predicates ...predicate.User) predicate.User {
|
func And(predicates ...predicate.User) predicate.User {
|
||||||
return predicate.User(sql.AndPredicates(predicates...))
|
return predicate.User(sql.AndPredicates(predicates...))
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"entgo.io/ent/schema/field"
|
"entgo.io/ent/schema/field"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
|
@ -181,6 +182,21 @@ func (uc *UserCreate) AddNotifiers(n ...*Notifier) *UserCreate {
|
||||||
return uc.AddNotifierIDs(ids...)
|
return uc.AddNotifierIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddActionTokenIDs adds the "action_tokens" edge to the ActionToken entity by IDs.
|
||||||
|
func (uc *UserCreate) AddActionTokenIDs(ids ...uuid.UUID) *UserCreate {
|
||||||
|
uc.mutation.AddActionTokenIDs(ids...)
|
||||||
|
return uc
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddActionTokens adds the "action_tokens" edges to the ActionToken entity.
|
||||||
|
func (uc *UserCreate) AddActionTokens(a ...*ActionToken) *UserCreate {
|
||||||
|
ids := make([]uuid.UUID, len(a))
|
||||||
|
for i := range a {
|
||||||
|
ids[i] = a[i].ID
|
||||||
|
}
|
||||||
|
return uc.AddActionTokenIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the UserMutation object of the builder.
|
// Mutation returns the UserMutation object of the builder.
|
||||||
func (uc *UserCreate) Mutation() *UserMutation {
|
func (uc *UserCreate) Mutation() *UserMutation {
|
||||||
return uc.mutation
|
return uc.mutation
|
||||||
|
@ -411,6 +427,22 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
||||||
}
|
}
|
||||||
_spec.Edges = append(_spec.Edges, edge)
|
_spec.Edges = append(_spec.Edges, edge)
|
||||||
}
|
}
|
||||||
|
if nodes := uc.mutation.ActionTokensIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: user.ActionTokensTable,
|
||||||
|
Columns: []string{user.ActionTokensColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges = append(_spec.Edges, edge)
|
||||||
|
}
|
||||||
return _node, _spec
|
return _node, _spec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"entgo.io/ent/schema/field"
|
"entgo.io/ent/schema/field"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
|
@ -22,14 +23,15 @@ import (
|
||||||
// UserQuery is the builder for querying User entities.
|
// UserQuery is the builder for querying User entities.
|
||||||
type UserQuery struct {
|
type UserQuery struct {
|
||||||
config
|
config
|
||||||
ctx *QueryContext
|
ctx *QueryContext
|
||||||
order []user.OrderOption
|
order []user.OrderOption
|
||||||
inters []Interceptor
|
inters []Interceptor
|
||||||
predicates []predicate.User
|
predicates []predicate.User
|
||||||
withGroup *GroupQuery
|
withGroup *GroupQuery
|
||||||
withAuthTokens *AuthTokensQuery
|
withAuthTokens *AuthTokensQuery
|
||||||
withNotifiers *NotifierQuery
|
withNotifiers *NotifierQuery
|
||||||
withFKs bool
|
withActionTokens *ActionTokenQuery
|
||||||
|
withFKs bool
|
||||||
// intermediate query (i.e. traversal path).
|
// intermediate query (i.e. traversal path).
|
||||||
sql *sql.Selector
|
sql *sql.Selector
|
||||||
path func(context.Context) (*sql.Selector, error)
|
path func(context.Context) (*sql.Selector, error)
|
||||||
|
@ -132,6 +134,28 @@ func (uq *UserQuery) QueryNotifiers() *NotifierQuery {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryActionTokens chains the current query on the "action_tokens" edge.
|
||||||
|
func (uq *UserQuery) QueryActionTokens() *ActionTokenQuery {
|
||||||
|
query := (&ActionTokenClient{config: uq.config}).Query()
|
||||||
|
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||||
|
if err := uq.prepareQuery(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
selector := uq.sqlQuery(ctx)
|
||||||
|
if err := selector.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
step := sqlgraph.NewStep(
|
||||||
|
sqlgraph.From(user.Table, user.FieldID, selector),
|
||||||
|
sqlgraph.To(actiontoken.Table, actiontoken.FieldID),
|
||||||
|
sqlgraph.Edge(sqlgraph.O2M, false, user.ActionTokensTable, user.ActionTokensColumn),
|
||||||
|
)
|
||||||
|
fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step)
|
||||||
|
return fromU, nil
|
||||||
|
}
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
|
||||||
// First returns the first User entity from the query.
|
// First returns the first User entity from the query.
|
||||||
// Returns a *NotFoundError when no User was found.
|
// Returns a *NotFoundError when no User was found.
|
||||||
func (uq *UserQuery) First(ctx context.Context) (*User, error) {
|
func (uq *UserQuery) First(ctx context.Context) (*User, error) {
|
||||||
|
@ -319,14 +343,15 @@ func (uq *UserQuery) Clone() *UserQuery {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &UserQuery{
|
return &UserQuery{
|
||||||
config: uq.config,
|
config: uq.config,
|
||||||
ctx: uq.ctx.Clone(),
|
ctx: uq.ctx.Clone(),
|
||||||
order: append([]user.OrderOption{}, uq.order...),
|
order: append([]user.OrderOption{}, uq.order...),
|
||||||
inters: append([]Interceptor{}, uq.inters...),
|
inters: append([]Interceptor{}, uq.inters...),
|
||||||
predicates: append([]predicate.User{}, uq.predicates...),
|
predicates: append([]predicate.User{}, uq.predicates...),
|
||||||
withGroup: uq.withGroup.Clone(),
|
withGroup: uq.withGroup.Clone(),
|
||||||
withAuthTokens: uq.withAuthTokens.Clone(),
|
withAuthTokens: uq.withAuthTokens.Clone(),
|
||||||
withNotifiers: uq.withNotifiers.Clone(),
|
withNotifiers: uq.withNotifiers.Clone(),
|
||||||
|
withActionTokens: uq.withActionTokens.Clone(),
|
||||||
// clone intermediate query.
|
// clone intermediate query.
|
||||||
sql: uq.sql.Clone(),
|
sql: uq.sql.Clone(),
|
||||||
path: uq.path,
|
path: uq.path,
|
||||||
|
@ -366,6 +391,17 @@ func (uq *UserQuery) WithNotifiers(opts ...func(*NotifierQuery)) *UserQuery {
|
||||||
return uq
|
return uq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithActionTokens tells the query-builder to eager-load the nodes that are connected to
|
||||||
|
// the "action_tokens" edge. The optional arguments are used to configure the query builder of the edge.
|
||||||
|
func (uq *UserQuery) WithActionTokens(opts ...func(*ActionTokenQuery)) *UserQuery {
|
||||||
|
query := (&ActionTokenClient{config: uq.config}).Query()
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(query)
|
||||||
|
}
|
||||||
|
uq.withActionTokens = query
|
||||||
|
return uq
|
||||||
|
}
|
||||||
|
|
||||||
// GroupBy is used to group vertices by one or more fields/columns.
|
// GroupBy is used to group vertices by one or more fields/columns.
|
||||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||||
//
|
//
|
||||||
|
@ -445,10 +481,11 @@ func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
|
||||||
nodes = []*User{}
|
nodes = []*User{}
|
||||||
withFKs = uq.withFKs
|
withFKs = uq.withFKs
|
||||||
_spec = uq.querySpec()
|
_spec = uq.querySpec()
|
||||||
loadedTypes = [3]bool{
|
loadedTypes = [4]bool{
|
||||||
uq.withGroup != nil,
|
uq.withGroup != nil,
|
||||||
uq.withAuthTokens != nil,
|
uq.withAuthTokens != nil,
|
||||||
uq.withNotifiers != nil,
|
uq.withNotifiers != nil,
|
||||||
|
uq.withActionTokens != nil,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if uq.withGroup != nil {
|
if uq.withGroup != nil {
|
||||||
|
@ -495,6 +532,13 @@ func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if query := uq.withActionTokens; query != nil {
|
||||||
|
if err := uq.loadActionTokens(ctx, query, nodes,
|
||||||
|
func(n *User) { n.Edges.ActionTokens = []*ActionToken{} },
|
||||||
|
func(n *User, e *ActionToken) { n.Edges.ActionTokens = append(n.Edges.ActionTokens, e) }); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
return nodes, nil
|
return nodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,6 +635,36 @@ func (uq *UserQuery) loadNotifiers(ctx context.Context, query *NotifierQuery, no
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (uq *UserQuery) loadActionTokens(ctx context.Context, query *ActionTokenQuery, nodes []*User, init func(*User), assign func(*User, *ActionToken)) error {
|
||||||
|
fks := make([]driver.Value, 0, len(nodes))
|
||||||
|
nodeids := make(map[uuid.UUID]*User)
|
||||||
|
for i := range nodes {
|
||||||
|
fks = append(fks, nodes[i].ID)
|
||||||
|
nodeids[nodes[i].ID] = nodes[i]
|
||||||
|
if init != nil {
|
||||||
|
init(nodes[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(query.ctx.Fields) > 0 {
|
||||||
|
query.ctx.AppendFieldOnce(actiontoken.FieldUserID)
|
||||||
|
}
|
||||||
|
query.Where(predicate.ActionToken(func(s *sql.Selector) {
|
||||||
|
s.Where(sql.InValues(s.C(user.ActionTokensColumn), fks...))
|
||||||
|
}))
|
||||||
|
neighbors, err := query.All(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, n := range neighbors {
|
||||||
|
fk := n.UserID
|
||||||
|
node, ok := nodeids[fk]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf(`unexpected referenced foreign-key "user_id" returned %v for node %v`, fk, n.ID)
|
||||||
|
}
|
||||||
|
assign(node, n)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) {
|
func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) {
|
||||||
_spec := uq.querySpec()
|
_spec := uq.querySpec()
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||||
"entgo.io/ent/schema/field"
|
"entgo.io/ent/schema/field"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||||
|
@ -183,6 +184,21 @@ func (uu *UserUpdate) AddNotifiers(n ...*Notifier) *UserUpdate {
|
||||||
return uu.AddNotifierIDs(ids...)
|
return uu.AddNotifierIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddActionTokenIDs adds the "action_tokens" edge to the ActionToken entity by IDs.
|
||||||
|
func (uu *UserUpdate) AddActionTokenIDs(ids ...uuid.UUID) *UserUpdate {
|
||||||
|
uu.mutation.AddActionTokenIDs(ids...)
|
||||||
|
return uu
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddActionTokens adds the "action_tokens" edges to the ActionToken entity.
|
||||||
|
func (uu *UserUpdate) AddActionTokens(a ...*ActionToken) *UserUpdate {
|
||||||
|
ids := make([]uuid.UUID, len(a))
|
||||||
|
for i := range a {
|
||||||
|
ids[i] = a[i].ID
|
||||||
|
}
|
||||||
|
return uu.AddActionTokenIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the UserMutation object of the builder.
|
// Mutation returns the UserMutation object of the builder.
|
||||||
func (uu *UserUpdate) Mutation() *UserMutation {
|
func (uu *UserUpdate) Mutation() *UserMutation {
|
||||||
return uu.mutation
|
return uu.mutation
|
||||||
|
@ -236,6 +252,27 @@ func (uu *UserUpdate) RemoveNotifiers(n ...*Notifier) *UserUpdate {
|
||||||
return uu.RemoveNotifierIDs(ids...)
|
return uu.RemoveNotifierIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearActionTokens clears all "action_tokens" edges to the ActionToken entity.
|
||||||
|
func (uu *UserUpdate) ClearActionTokens() *UserUpdate {
|
||||||
|
uu.mutation.ClearActionTokens()
|
||||||
|
return uu
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveActionTokenIDs removes the "action_tokens" edge to ActionToken entities by IDs.
|
||||||
|
func (uu *UserUpdate) RemoveActionTokenIDs(ids ...uuid.UUID) *UserUpdate {
|
||||||
|
uu.mutation.RemoveActionTokenIDs(ids...)
|
||||||
|
return uu
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveActionTokens removes "action_tokens" edges to ActionToken entities.
|
||||||
|
func (uu *UserUpdate) RemoveActionTokens(a ...*ActionToken) *UserUpdate {
|
||||||
|
ids := make([]uuid.UUID, len(a))
|
||||||
|
for i := range a {
|
||||||
|
ids[i] = a[i].ID
|
||||||
|
}
|
||||||
|
return uu.RemoveActionTokenIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||||
func (uu *UserUpdate) Save(ctx context.Context) (int, error) {
|
func (uu *UserUpdate) Save(ctx context.Context) (int, error) {
|
||||||
uu.defaults()
|
uu.defaults()
|
||||||
|
@ -458,6 +495,51 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||||
}
|
}
|
||||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
}
|
}
|
||||||
|
if uu.mutation.ActionTokensCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: user.ActionTokensTable,
|
||||||
|
Columns: []string{user.ActionTokensColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := uu.mutation.RemovedActionTokensIDs(); len(nodes) > 0 && !uu.mutation.ActionTokensCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: user.ActionTokensTable,
|
||||||
|
Columns: []string{user.ActionTokensColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := uu.mutation.ActionTokensIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: user.ActionTokensTable,
|
||||||
|
Columns: []string{user.ActionTokensColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
|
}
|
||||||
if n, err = sqlgraph.UpdateNodes(ctx, uu.driver, _spec); err != nil {
|
if n, err = sqlgraph.UpdateNodes(ctx, uu.driver, _spec); err != nil {
|
||||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||||
err = &NotFoundError{user.Label}
|
err = &NotFoundError{user.Label}
|
||||||
|
@ -629,6 +711,21 @@ func (uuo *UserUpdateOne) AddNotifiers(n ...*Notifier) *UserUpdateOne {
|
||||||
return uuo.AddNotifierIDs(ids...)
|
return uuo.AddNotifierIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddActionTokenIDs adds the "action_tokens" edge to the ActionToken entity by IDs.
|
||||||
|
func (uuo *UserUpdateOne) AddActionTokenIDs(ids ...uuid.UUID) *UserUpdateOne {
|
||||||
|
uuo.mutation.AddActionTokenIDs(ids...)
|
||||||
|
return uuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddActionTokens adds the "action_tokens" edges to the ActionToken entity.
|
||||||
|
func (uuo *UserUpdateOne) AddActionTokens(a ...*ActionToken) *UserUpdateOne {
|
||||||
|
ids := make([]uuid.UUID, len(a))
|
||||||
|
for i := range a {
|
||||||
|
ids[i] = a[i].ID
|
||||||
|
}
|
||||||
|
return uuo.AddActionTokenIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Mutation returns the UserMutation object of the builder.
|
// Mutation returns the UserMutation object of the builder.
|
||||||
func (uuo *UserUpdateOne) Mutation() *UserMutation {
|
func (uuo *UserUpdateOne) Mutation() *UserMutation {
|
||||||
return uuo.mutation
|
return uuo.mutation
|
||||||
|
@ -682,6 +779,27 @@ func (uuo *UserUpdateOne) RemoveNotifiers(n ...*Notifier) *UserUpdateOne {
|
||||||
return uuo.RemoveNotifierIDs(ids...)
|
return uuo.RemoveNotifierIDs(ids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearActionTokens clears all "action_tokens" edges to the ActionToken entity.
|
||||||
|
func (uuo *UserUpdateOne) ClearActionTokens() *UserUpdateOne {
|
||||||
|
uuo.mutation.ClearActionTokens()
|
||||||
|
return uuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveActionTokenIDs removes the "action_tokens" edge to ActionToken entities by IDs.
|
||||||
|
func (uuo *UserUpdateOne) RemoveActionTokenIDs(ids ...uuid.UUID) *UserUpdateOne {
|
||||||
|
uuo.mutation.RemoveActionTokenIDs(ids...)
|
||||||
|
return uuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveActionTokens removes "action_tokens" edges to ActionToken entities.
|
||||||
|
func (uuo *UserUpdateOne) RemoveActionTokens(a ...*ActionToken) *UserUpdateOne {
|
||||||
|
ids := make([]uuid.UUID, len(a))
|
||||||
|
for i := range a {
|
||||||
|
ids[i] = a[i].ID
|
||||||
|
}
|
||||||
|
return uuo.RemoveActionTokenIDs(ids...)
|
||||||
|
}
|
||||||
|
|
||||||
// Where appends a list predicates to the UserUpdate builder.
|
// Where appends a list predicates to the UserUpdate builder.
|
||||||
func (uuo *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne {
|
func (uuo *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne {
|
||||||
uuo.mutation.Where(ps...)
|
uuo.mutation.Where(ps...)
|
||||||
|
@ -934,6 +1052,51 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error)
|
||||||
}
|
}
|
||||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
}
|
}
|
||||||
|
if uuo.mutation.ActionTokensCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: user.ActionTokensTable,
|
||||||
|
Columns: []string{user.ActionTokensColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := uuo.mutation.RemovedActionTokensIDs(); len(nodes) > 0 && !uuo.mutation.ActionTokensCleared() {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: user.ActionTokensTable,
|
||||||
|
Columns: []string{user.ActionTokensColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||||
|
}
|
||||||
|
if nodes := uuo.mutation.ActionTokensIDs(); len(nodes) > 0 {
|
||||||
|
edge := &sqlgraph.EdgeSpec{
|
||||||
|
Rel: sqlgraph.O2M,
|
||||||
|
Inverse: false,
|
||||||
|
Table: user.ActionTokensTable,
|
||||||
|
Columns: []string{user.ActionTokensColumn},
|
||||||
|
Bidi: false,
|
||||||
|
Target: &sqlgraph.EdgeTarget{
|
||||||
|
IDSpec: sqlgraph.NewFieldSpec(actiontoken.FieldID, field.TypeUUID),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, k := range nodes {
|
||||||
|
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||||
|
}
|
||||||
|
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||||
|
}
|
||||||
_node = &User{config: uuo.config}
|
_node = &User{config: uuo.config}
|
||||||
_spec.Assign = _node.assignValues
|
_spec.Assign = _node.assignValues
|
||||||
_spec.ScanValues = _node.scanValues
|
_spec.ScanValues = _node.scanValues
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
-- Create "action_tokens" table
|
||||||
|
CREATE TABLE `action_tokens` (`id` uuid NOT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, `action` text NOT NULL DEFAULT ('reset_password'), `token` blob NOT NULL, `user_id` uuid NOT NULL, PRIMARY KEY (`id`), CONSTRAINT `action_tokens_users_action_tokens` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE);
|
||||||
|
-- Create index "action_tokens_token_key" to table: "action_tokens"
|
||||||
|
CREATE UNIQUE INDEX `action_tokens_token_key` ON `action_tokens` (`token`);
|
||||||
|
-- Create index "actiontoken_token" to table: "action_tokens"
|
||||||
|
CREATE INDEX `actiontoken_token` ON `action_tokens` (`token`);
|
||||||
|
-- Create index "actiontoken_action" to table: "action_tokens"
|
||||||
|
CREATE INDEX `actiontoken_action` ON `action_tokens` (`action`);
|
||||||
|
-- Create index "actiontoken_user_id" to table: "action_tokens"
|
||||||
|
CREATE INDEX `actiontoken_user_id` ON `action_tokens` (`user_id`);
|
|
@ -1,4 +1,4 @@
|
||||||
h1:sjJCTAqc9FG8BKBIzh5ZynYD/Ilz6vnLqM4XX83WQ4M=
|
h1:6CJ6qlt5IqAoKF6R9yH8Ei2eqkAbkCqjM1dDUvA24f8=
|
||||||
20220929052825_init.sql h1:ZlCqm1wzjDmofeAcSX3jE4h4VcdTNGpRg2eabztDy9Q=
|
20220929052825_init.sql h1:ZlCqm1wzjDmofeAcSX3jE4h4VcdTNGpRg2eabztDy9Q=
|
||||||
20221001210956_group_invitations.sql h1:YQKJFtE39wFOcRNbZQ/d+ZlHwrcfcsZlcv/pLEYdpjw=
|
20221001210956_group_invitations.sql h1:YQKJFtE39wFOcRNbZQ/d+ZlHwrcfcsZlcv/pLEYdpjw=
|
||||||
20221009173029_add_user_roles.sql h1:vWmzAfgEWQeGk0Vn70zfVPCcfEZth3E0JcvyKTjpYyU=
|
20221009173029_add_user_roles.sql h1:vWmzAfgEWQeGk0Vn70zfVPCcfEZth3E0JcvyKTjpYyU=
|
||||||
|
@ -13,3 +13,4 @@ h1:sjJCTAqc9FG8BKBIzh5ZynYD/Ilz6vnLqM4XX83WQ4M=
|
||||||
20230305065819_add_notifier_types.sql h1:r5xrgCKYQ2o9byBqYeAX1zdp94BLdaxf4vq9OmGHNl0=
|
20230305065819_add_notifier_types.sql h1:r5xrgCKYQ2o9byBqYeAX1zdp94BLdaxf4vq9OmGHNl0=
|
||||||
20230305071524_add_group_id_to_notifiers.sql h1:xDShqbyClcFhvJbwclOHdczgXbdffkxXNWjV61hL/t4=
|
20230305071524_add_group_id_to_notifiers.sql h1:xDShqbyClcFhvJbwclOHdczgXbdffkxXNWjV61hL/t4=
|
||||||
20231006213457_add_primary_attachment_flag.sql h1:J4tMSJQFa7vaj0jpnh8YKTssdyIjRyq6RXDXZIzDDu4=
|
20231006213457_add_primary_attachment_flag.sql h1:J4tMSJQFa7vaj0jpnh8YKTssdyIjRyq6RXDXZIzDDu4=
|
||||||
|
20240302172225_user_action_tokens.sql h1:nAdtVdh9O7p/AyKnURvZcS0H/Zoj1sM9HpwCOO09zDE=
|
||||||
|
|
|
@ -16,9 +16,9 @@ func (aid AssetID) Int() int {
|
||||||
return int(aid)
|
return int(aid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseAssetIDBytes(d []byte) (AID AssetID, ok bool) {
|
func ParseAssetIDBytes(d []byte) (assetID AssetID, ok bool) {
|
||||||
d = bytes.Replace(d, []byte(`"`), []byte(``), -1)
|
d = bytes.ReplaceAll(d, []byte(`"`), []byte(``))
|
||||||
d = bytes.Replace(d, []byte(`-`), []byte(``), -1)
|
d = bytes.ReplaceAll(d, []byte(`-`), []byte(``))
|
||||||
|
|
||||||
aidInt, err := strconv.Atoi(string(d))
|
aidInt, err := strconv.Atoi(string(d))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28,7 +28,7 @@ func ParseAssetIDBytes(d []byte) (AID AssetID, ok bool) {
|
||||||
return AssetID(aidInt), true
|
return AssetID(aidInt), true
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseAssetID(s string) (AID AssetID, ok bool) {
|
func ParseAssetID(s string) (assetID AssetID, ok bool) {
|
||||||
return ParseAssetIDBytes([]byte(s))
|
return ParseAssetIDBytes([]byte(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ func (aid *AssetID) UnmarshalJSON(d []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
d = bytes.Replace(d, []byte(`"`), []byte(``), -1)
|
d = bytes.ReplaceAll(d, []byte(`"`), []byte(``))
|
||||||
d = bytes.Replace(d, []byte(`-`), []byte(``), -1)
|
d = bytes.ReplaceAll(d, []byte(`-`), []byte(``))
|
||||||
|
|
||||||
aidInt, err := strconv.Atoi(string(d))
|
aidInt, err := strconv.Atoi(string(d))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -56,9 +56,10 @@ func TestMain(m *testing.M) {
|
||||||
|
|
||||||
tClient = client
|
tClient = client
|
||||||
tRepos = New(tClient, tbus, os.TempDir())
|
tRepos = New(tClient, tbus, os.TempDir())
|
||||||
defer func() { _ = client.Close() }()
|
|
||||||
|
|
||||||
bootstrap()
|
bootstrap()
|
||||||
|
|
||||||
os.Exit(m.Run())
|
exit := m.Run()
|
||||||
|
_ = client.Close()
|
||||||
|
os.Exit(exit)
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,12 +109,12 @@ func (r *GroupRepository) GetAllGroups(ctx context.Context) ([]Group, error) {
|
||||||
return r.groupMapper.MapEachErr(r.db.Group.Query().All(ctx))
|
return r.groupMapper.MapEachErr(r.db.Group.Query().All(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GroupRepository) StatsLocationsByPurchasePrice(ctx context.Context, GID uuid.UUID) ([]TotalsByOrganizer, error) {
|
func (r *GroupRepository) StatsLocationsByPurchasePrice(ctx context.Context, groupID uuid.UUID) ([]TotalsByOrganizer, error) {
|
||||||
var v []TotalsByOrganizer
|
var v []TotalsByOrganizer
|
||||||
|
|
||||||
err := r.db.Location.Query().
|
err := r.db.Location.Query().
|
||||||
Where(
|
Where(
|
||||||
location.HasGroupWith(group.ID(GID)),
|
location.HasGroupWith(group.ID(groupID)),
|
||||||
).
|
).
|
||||||
GroupBy(location.FieldID, location.FieldName).
|
GroupBy(location.FieldID, location.FieldName).
|
||||||
Aggregate(func(sq *sql.Selector) string {
|
Aggregate(func(sq *sql.Selector) string {
|
||||||
|
@ -131,12 +131,12 @@ func (r *GroupRepository) StatsLocationsByPurchasePrice(ctx context.Context, GID
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GroupRepository) StatsLabelsByPurchasePrice(ctx context.Context, GID uuid.UUID) ([]TotalsByOrganizer, error) {
|
func (r *GroupRepository) StatsLabelsByPurchasePrice(ctx context.Context, groupID uuid.UUID) ([]TotalsByOrganizer, error) {
|
||||||
var v []TotalsByOrganizer
|
var v []TotalsByOrganizer
|
||||||
|
|
||||||
err := r.db.Label.Query().
|
err := r.db.Label.Query().
|
||||||
Where(
|
Where(
|
||||||
label.HasGroupWith(group.ID(GID)),
|
label.HasGroupWith(group.ID(groupID)),
|
||||||
).
|
).
|
||||||
GroupBy(label.FieldID, label.FieldName).
|
GroupBy(label.FieldID, label.FieldName).
|
||||||
Aggregate(func(sq *sql.Selector) string {
|
Aggregate(func(sq *sql.Selector) string {
|
||||||
|
@ -157,7 +157,7 @@ func (r *GroupRepository) StatsLabelsByPurchasePrice(ctx context.Context, GID uu
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID, start, end time.Time) (*ValueOverTime, error) {
|
func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, groupID uuid.UUID, start, end time.Time) (*ValueOverTime, error) {
|
||||||
// Get the Totals for the Start and End of the Given Time Period
|
// Get the Totals for the Start and End of the Given Time Period
|
||||||
q := `
|
q := `
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -180,7 +180,7 @@ func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID,
|
||||||
var maybeStart *float64
|
var maybeStart *float64
|
||||||
var maybeEnd *float64
|
var maybeEnd *float64
|
||||||
|
|
||||||
row := r.db.Sql().QueryRowContext(ctx, q, GID, sqliteDateFormat(start), GID, sqliteDateFormat(end))
|
row := r.db.Sql().QueryRowContext(ctx, q, groupID, sqliteDateFormat(start), groupID, sqliteDateFormat(end))
|
||||||
err := row.Scan(&maybeStart, &maybeEnd)
|
err := row.Scan(&maybeStart, &maybeEnd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -198,7 +198,7 @@ func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID,
|
||||||
// Get Created Date and Price of all items between start and end
|
// Get Created Date and Price of all items between start and end
|
||||||
err = r.db.Item.Query().
|
err = r.db.Item.Query().
|
||||||
Where(
|
Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
item.CreatedAtGTE(start),
|
item.CreatedAtGTE(start),
|
||||||
item.CreatedAtLTE(end),
|
item.CreatedAtLTE(end),
|
||||||
item.Archived(false),
|
item.Archived(false),
|
||||||
|
@ -209,7 +209,6 @@ func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID,
|
||||||
item.FieldPurchasePrice,
|
item.FieldPurchasePrice,
|
||||||
).
|
).
|
||||||
Scan(ctx, &v)
|
Scan(ctx, &v)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -226,7 +225,7 @@ func (r *GroupRepository) StatsPurchasePrice(ctx context.Context, GID uuid.UUID,
|
||||||
return &stats, nil
|
return &stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GroupRepository) StatsGroup(ctx context.Context, GID uuid.UUID) (GroupStatistics, error) {
|
func (r *GroupRepository) StatsGroup(ctx context.Context, groupID uuid.UUID) (GroupStatistics, error) {
|
||||||
q := `
|
q := `
|
||||||
SELECT
|
SELECT
|
||||||
(SELECT COUNT(*) FROM users WHERE group_users = ?) AS total_users,
|
(SELECT COUNT(*) FROM users WHERE group_users = ?) AS total_users,
|
||||||
|
@ -242,7 +241,7 @@ func (r *GroupRepository) StatsGroup(ctx context.Context, GID uuid.UUID) (GroupS
|
||||||
) AS total_with_warranty
|
) AS total_with_warranty
|
||||||
`
|
`
|
||||||
var stats GroupStatistics
|
var stats GroupStatistics
|
||||||
row := r.db.Sql().QueryRowContext(ctx, q, GID, GID, GID, GID, GID, GID)
|
row := r.db.Sql().QueryRowContext(ctx, q, groupID, groupID, groupID, groupID, groupID, groupID)
|
||||||
|
|
||||||
var maybeTotalItemPrice *float64
|
var maybeTotalItemPrice *float64
|
||||||
var maybeTotalWithWarranty *int
|
var maybeTotalWithWarranty *int
|
||||||
|
@ -264,8 +263,8 @@ func (r *GroupRepository) GroupCreate(ctx context.Context, name string) (Group,
|
||||||
Save(ctx))
|
Save(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GroupRepository) GroupUpdate(ctx context.Context, ID uuid.UUID, data GroupUpdate) (Group, error) {
|
func (r *GroupRepository) GroupUpdate(ctx context.Context, groupID uuid.UUID, data GroupUpdate) (Group, error) {
|
||||||
entity, err := r.db.Group.UpdateOneID(ID).
|
entity, err := r.db.Group.UpdateOneID(groupID).
|
||||||
SetName(data.Name).
|
SetName(data.Name).
|
||||||
SetCurrency(strings.ToLower(data.Currency)).
|
SetCurrency(strings.ToLower(data.Currency)).
|
||||||
Save(ctx)
|
Save(ctx)
|
||||||
|
@ -273,8 +272,8 @@ func (r *GroupRepository) GroupUpdate(ctx context.Context, ID uuid.UUID, data Gr
|
||||||
return r.groupMapper.MapErr(entity, err)
|
return r.groupMapper.MapErr(entity, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GroupRepository) GroupByID(ctx context.Context, id uuid.UUID) (Group, error) {
|
func (r *GroupRepository) GroupByID(ctx context.Context, groupID uuid.UUID) (Group, error) {
|
||||||
return r.groupMapper.MapErr(r.db.Group.Get(ctx, id))
|
return r.groupMapper.MapErr(r.db.Group.Get(ctx, groupID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *GroupRepository) InvitationGet(ctx context.Context, token []byte) (GroupInvitation, error) {
|
func (r *GroupRepository) InvitationGet(ctx context.Context, token []byte) (GroupInvitation, error) {
|
||||||
|
|
|
@ -276,9 +276,9 @@ func mapItemOut(item *ent.Item) ItemOut {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) publishMutationEvent(GID uuid.UUID) {
|
func (e *ItemsRepository) publishMutationEvent(groupID uuid.UUID) {
|
||||||
if e.bus != nil {
|
if e.bus != nil {
|
||||||
e.bus.Publish(eventbus.EventItemMutation, eventbus.GroupMutationEvent{GID: GID})
|
e.bus.Publish(eventbus.EventItemMutation, eventbus.GroupMutationEvent{GID: groupID})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,13 +304,13 @@ func (e *ItemsRepository) GetOne(ctx context.Context, id uuid.UUID) (ItemOut, er
|
||||||
return e.getOne(ctx, item.ID(id))
|
return e.getOne(ctx, item.ID(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) CheckRef(ctx context.Context, GID uuid.UUID, ref string) (bool, error) {
|
func (e *ItemsRepository) CheckRef(ctx context.Context, groupID uuid.UUID, ref string) (bool, error) {
|
||||||
q := e.db.Item.Query().Where(item.HasGroupWith(group.ID(GID)))
|
q := e.db.Item.Query().Where(item.HasGroupWith(group.ID(groupID)))
|
||||||
return q.Where(item.ImportRef(ref)).Exist(ctx)
|
return q.Where(item.ImportRef(ref)).Exist(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) GetByRef(ctx context.Context, GID uuid.UUID, ref string) (ItemOut, error) {
|
func (e *ItemsRepository) GetByRef(ctx context.Context, groupID uuid.UUID, ref string) (ItemOut, error) {
|
||||||
return e.getOne(ctx, item.ImportRef(ref), item.HasGroupWith(group.ID(GID)))
|
return e.getOne(ctx, item.ImportRef(ref), item.HasGroupWith(group.ID(groupID)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOneByGroup returns a single item by ID. If the item does not exist, an error is returned.
|
// GetOneByGroup returns a single item by ID. If the item does not exist, an error is returned.
|
||||||
|
@ -490,9 +490,9 @@ func (e *ItemsRepository) GetAll(ctx context.Context, gid uuid.UUID) ([]ItemOut,
|
||||||
All(ctx))
|
All(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) GetAllZeroAssetID(ctx context.Context, GID uuid.UUID) ([]ItemSummary, error) {
|
func (e *ItemsRepository) GetAllZeroAssetID(ctx context.Context, groupID uuid.UUID) ([]ItemSummary, error) {
|
||||||
q := e.db.Item.Query().Where(
|
q := e.db.Item.Query().Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
item.AssetID(0),
|
item.AssetID(0),
|
||||||
).Order(
|
).Order(
|
||||||
ent.Asc(item.FieldCreatedAt),
|
ent.Asc(item.FieldCreatedAt),
|
||||||
|
@ -501,9 +501,9 @@ func (e *ItemsRepository) GetAllZeroAssetID(ctx context.Context, GID uuid.UUID)
|
||||||
return mapItemsSummaryErr(q.All(ctx))
|
return mapItemsSummaryErr(q.All(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) GetHighestAssetID(ctx context.Context, GID uuid.UUID) (AssetID, error) {
|
func (e *ItemsRepository) GetHighestAssetID(ctx context.Context, groupID uuid.UUID) (AssetID, error) {
|
||||||
q := e.db.Item.Query().Where(
|
q := e.db.Item.Query().Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
).Order(
|
).Order(
|
||||||
ent.Desc(item.FieldAssetID),
|
ent.Desc(item.FieldAssetID),
|
||||||
).Limit(1)
|
).Limit(1)
|
||||||
|
@ -519,10 +519,10 @@ func (e *ItemsRepository) GetHighestAssetID(ctx context.Context, GID uuid.UUID)
|
||||||
return AssetID(result.AssetID), nil
|
return AssetID(result.AssetID), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) SetAssetID(ctx context.Context, GID uuid.UUID, ID uuid.UUID, assetID AssetID) error {
|
func (e *ItemsRepository) SetAssetID(ctx context.Context, groupID uuid.UUID, itemID uuid.UUID, assetID AssetID) error {
|
||||||
q := e.db.Item.Update().Where(
|
q := e.db.Item.Update().Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
item.ID(ID),
|
item.ID(itemID),
|
||||||
)
|
)
|
||||||
|
|
||||||
_, err := q.SetAssetID(int(assetID)).Save(ctx)
|
_, err := q.SetAssetID(int(assetID)).Save(ctx)
|
||||||
|
@ -576,8 +576,8 @@ func (e *ItemsRepository) DeleteByGroup(ctx context.Context, gid, id uuid.UUID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data ItemUpdate) (ItemOut, error) {
|
func (e *ItemsRepository) UpdateByGroup(ctx context.Context, groupID uuid.UUID, data ItemUpdate) (ItemOut, error) {
|
||||||
q := e.db.Item.Update().Where(item.ID(data.ID), item.HasGroupWith(group.ID(GID))).
|
q := e.db.Item.Update().Where(item.ID(data.ID), item.HasGroupWith(group.ID(groupID))).
|
||||||
SetName(data.Name).
|
SetName(data.Name).
|
||||||
SetDescription(data.Description).
|
SetDescription(data.Description).
|
||||||
SetLocationID(data.LocationID).
|
SetLocationID(data.LocationID).
|
||||||
|
@ -688,16 +688,16 @@ func (e *ItemsRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.publishMutationEvent(GID)
|
e.publishMutationEvent(groupID)
|
||||||
return e.GetOne(ctx, data.ID)
|
return e.GetOne(ctx, data.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) GetAllZeroImportRef(ctx context.Context, GID uuid.UUID) ([]uuid.UUID, error) {
|
func (e *ItemsRepository) GetAllZeroImportRef(ctx context.Context, groupID uuid.UUID) ([]uuid.UUID, error) {
|
||||||
var ids []uuid.UUID
|
var ids []uuid.UUID
|
||||||
|
|
||||||
err := e.db.Item.Query().
|
err := e.db.Item.Query().
|
||||||
Where(
|
Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
item.Or(
|
item.Or(
|
||||||
item.ImportRefEQ(""),
|
item.ImportRefEQ(""),
|
||||||
item.ImportRefIsNil(),
|
item.ImportRefIsNil(),
|
||||||
|
@ -712,11 +712,11 @@ func (e *ItemsRepository) GetAllZeroImportRef(ctx context.Context, GID uuid.UUID
|
||||||
return ids, nil
|
return ids, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) Patch(ctx context.Context, GID, ID uuid.UUID, data ItemPatch) error {
|
func (e *ItemsRepository) Patch(ctx context.Context, groupID, itemID uuid.UUID, data ItemPatch) error {
|
||||||
q := e.db.Item.Update().
|
q := e.db.Item.Update().
|
||||||
Where(
|
Where(
|
||||||
item.ID(ID),
|
item.ID(itemID),
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
)
|
)
|
||||||
|
|
||||||
if data.ImportRef != nil {
|
if data.ImportRef != nil {
|
||||||
|
@ -727,11 +727,11 @@ func (e *ItemsRepository) Patch(ctx context.Context, GID, ID uuid.UUID, data Ite
|
||||||
q.SetQuantity(*data.Quantity)
|
q.SetQuantity(*data.Quantity)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.publishMutationEvent(GID)
|
e.publishMutationEvent(groupID)
|
||||||
return q.Exec(ctx)
|
return q.Exec(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.UUID, name string) ([]string, error) {
|
func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, groupID uuid.UUID, name string) ([]string, error) {
|
||||||
type st struct {
|
type st struct {
|
||||||
Value string `json:"text_value"`
|
Value string `json:"text_value"`
|
||||||
}
|
}
|
||||||
|
@ -740,7 +740,7 @@ func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.
|
||||||
|
|
||||||
err := e.db.Item.Query().
|
err := e.db.Item.Query().
|
||||||
Where(
|
Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
).
|
).
|
||||||
QueryFields().
|
QueryFields().
|
||||||
Where(
|
Where(
|
||||||
|
@ -761,7 +761,7 @@ func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.
|
||||||
return valueStrings, nil
|
return valueStrings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.UUID) ([]string, error) {
|
func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, groupID uuid.UUID) ([]string, error) {
|
||||||
type st struct {
|
type st struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
@ -770,7 +770,7 @@ func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.U
|
||||||
|
|
||||||
err := e.db.Item.Query().
|
err := e.db.Item.Query().
|
||||||
Where(
|
Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
).
|
).
|
||||||
QueryFields().
|
QueryFields().
|
||||||
Unique(true).
|
Unique(true).
|
||||||
|
@ -794,9 +794,9 @@ func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.U
|
||||||
// This is designed to resolve a long-time bug that has since been fixed with the time selector on the
|
// This is designed to resolve a long-time bug that has since been fixed with the time selector on the
|
||||||
// frontend. This function is intended to be used as a one-time fix for existing databases and may be
|
// frontend. This function is intended to be used as a one-time fix for existing databases and may be
|
||||||
// removed in the future.
|
// removed in the future.
|
||||||
func (e *ItemsRepository) ZeroOutTimeFields(ctx context.Context, GID uuid.UUID) (int, error) {
|
func (e *ItemsRepository) ZeroOutTimeFields(ctx context.Context, groupID uuid.UUID) (int, error) {
|
||||||
q := e.db.Item.Query().Where(
|
q := e.db.Item.Query().Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
item.Or(
|
item.Or(
|
||||||
item.PurchaseTimeNotNil(),
|
item.PurchaseTimeNotNil(),
|
||||||
item.PurchaseFromLT("0002-01-01"),
|
item.PurchaseFromLT("0002-01-01"),
|
||||||
|
@ -865,11 +865,11 @@ func (e *ItemsRepository) ZeroOutTimeFields(ctx context.Context, GID uuid.UUID)
|
||||||
return updated, nil
|
return updated, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ItemsRepository) SetPrimaryPhotos(ctx context.Context, GID uuid.UUID) (int, error) {
|
func (e *ItemsRepository) SetPrimaryPhotos(ctx context.Context, groupID uuid.UUID) (int, error) {
|
||||||
// All items where there is no primary photo
|
// All items where there is no primary photo
|
||||||
itemIDs, err := e.db.Item.Query().
|
itemIDs, err := e.db.Item.Query().
|
||||||
Where(
|
Where(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
item.HasAttachmentsWith(
|
item.HasAttachmentsWith(
|
||||||
attachment.TypeEQ(attachment.TypePhoto),
|
attachment.TypeEQ(attachment.TypePhoto),
|
||||||
attachment.Not(
|
attachment.Not(
|
||||||
|
|
|
@ -65,9 +65,9 @@ func mapLabelOut(label *ent.Label) LabelOut {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LabelRepository) publishMutationEvent(GID uuid.UUID) {
|
func (r *LabelRepository) publishMutationEvent(groupID uuid.UUID) {
|
||||||
if r.bus != nil {
|
if r.bus != nil {
|
||||||
r.bus.Publish(eventbus.EventLabelMutation, eventbus.GroupMutationEvent{GID: GID})
|
r.bus.Publish(eventbus.EventLabelMutation, eventbus.GroupMutationEvent{GID: groupID})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ func (r *LabelRepository) getOne(ctx context.Context, where ...predicate.Label)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LabelRepository) GetOne(ctx context.Context, ID uuid.UUID) (LabelOut, error) {
|
func (r *LabelRepository) GetOne(ctx context.Context, labelID uuid.UUID) (LabelOut, error) {
|
||||||
return r.getOne(ctx, label.ID(ID))
|
return r.getOne(ctx, label.ID(labelID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LabelRepository) GetOneByGroup(ctx context.Context, gid, ld uuid.UUID) (LabelOut, error) {
|
func (r *LabelRepository) GetOneByGroup(ctx context.Context, gid, ld uuid.UUID) (LabelOut, error) {
|
||||||
|
@ -125,13 +125,13 @@ func (r *LabelRepository) update(ctx context.Context, data LabelUpdate, where ..
|
||||||
Save(ctx)
|
Save(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LabelRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data LabelUpdate) (LabelOut, error) {
|
func (r *LabelRepository) UpdateByGroup(ctx context.Context, groupID uuid.UUID, data LabelUpdate) (LabelOut, error) {
|
||||||
_, err := r.update(ctx, data, label.ID(data.ID), label.HasGroupWith(group.ID(GID)))
|
_, err := r.update(ctx, data, label.ID(data.ID), label.HasGroupWith(group.ID(groupID)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LabelOut{}, err
|
return LabelOut{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
r.publishMutationEvent(GID)
|
r.publishMutationEvent(groupID)
|
||||||
return r.GetOne(ctx, data.ID)
|
return r.GetOne(ctx, data.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,9 +89,9 @@ func mapLocationOut(location *ent.Location) LocationOut {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) publishMutationEvent(GID uuid.UUID) {
|
func (r *LocationRepository) publishMutationEvent(groupID uuid.UUID) {
|
||||||
if r.bus != nil {
|
if r.bus != nil {
|
||||||
r.bus.Publish(eventbus.EventLocationMutation, eventbus.GroupMutationEvent{GID: GID})
|
r.bus.Publish(eventbus.EventLocationMutation, eventbus.GroupMutationEvent{GID: groupID})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ type LocationQuery struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAll returns all locations with item count field populated
|
// GetAll returns all locations with item count field populated
|
||||||
func (r *LocationRepository) GetAll(ctx context.Context, GID uuid.UUID, filter LocationQuery) ([]LocationOutCount, error) {
|
func (r *LocationRepository) GetAll(ctx context.Context, groupID uuid.UUID, filter LocationQuery) ([]LocationOutCount, error) {
|
||||||
query := `--sql
|
query := `--sql
|
||||||
SELECT
|
SELECT
|
||||||
id,
|
id,
|
||||||
|
@ -131,7 +131,7 @@ func (r *LocationRepository) GetAll(ctx context.Context, GID uuid.UUID, filter L
|
||||||
query = strings.Replace(query, "{{ FILTER_CHILDREN }}", "", 1)
|
query = strings.Replace(query, "{{ FILTER_CHILDREN }}", "", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := r.db.Sql().QueryContext(ctx, query, GID)
|
rows, err := r.db.Sql().QueryContext(ctx, query, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -167,19 +167,19 @@ func (r *LocationRepository) getOne(ctx context.Context, where ...predicate.Loca
|
||||||
Only(ctx))
|
Only(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) Get(ctx context.Context, ID uuid.UUID) (LocationOut, error) {
|
func (r *LocationRepository) Get(ctx context.Context, locationID uuid.UUID) (LocationOut, error) {
|
||||||
return r.getOne(ctx, location.ID(ID))
|
return r.getOne(ctx, location.ID(locationID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) GetOneByGroup(ctx context.Context, GID, ID uuid.UUID) (LocationOut, error) {
|
func (r *LocationRepository) GetOneByGroup(ctx context.Context, groupID, locationID uuid.UUID) (LocationOut, error) {
|
||||||
return r.getOne(ctx, location.ID(ID), location.HasGroupWith(group.ID(GID)))
|
return r.getOne(ctx, location.ID(locationID), location.HasGroupWith(group.ID(groupID)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) Create(ctx context.Context, GID uuid.UUID, data LocationCreate) (LocationOut, error) {
|
func (r *LocationRepository) Create(ctx context.Context, groupID uuid.UUID, data LocationCreate) (LocationOut, error) {
|
||||||
q := r.db.Location.Create().
|
q := r.db.Location.Create().
|
||||||
SetName(data.Name).
|
SetName(data.Name).
|
||||||
SetDescription(data.Description).
|
SetDescription(data.Description).
|
||||||
SetGroupID(GID)
|
SetGroupID(groupID)
|
||||||
|
|
||||||
if data.ParentID != uuid.Nil {
|
if data.ParentID != uuid.Nil {
|
||||||
q.SetParentID(data.ParentID)
|
q.SetParentID(data.ParentID)
|
||||||
|
@ -190,8 +190,8 @@ func (r *LocationRepository) Create(ctx context.Context, GID uuid.UUID, data Loc
|
||||||
return LocationOut{}, err
|
return LocationOut{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
location.Edges.Group = &ent.Group{ID: GID} // bootstrap group ID
|
location.Edges.Group = &ent.Group{ID: groupID} // bootstrap group ID
|
||||||
r.publishMutationEvent(GID)
|
r.publishMutationEvent(groupID)
|
||||||
return mapLocationOut(location), nil
|
return mapLocationOut(location), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,28 +215,28 @@ func (r *LocationRepository) update(ctx context.Context, data LocationUpdate, wh
|
||||||
return r.Get(ctx, data.ID)
|
return r.Get(ctx, data.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) UpdateByGroup(ctx context.Context, GID, ID uuid.UUID, data LocationUpdate) (LocationOut, error) {
|
func (r *LocationRepository) UpdateByGroup(ctx context.Context, groupID, locationID uuid.UUID, data LocationUpdate) (LocationOut, error) {
|
||||||
v, err := r.update(ctx, data, location.ID(ID), location.HasGroupWith(group.ID(GID)))
|
v, err := r.update(ctx, data, location.ID(locationID), location.HasGroupWith(group.ID(groupID)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return LocationOut{}, err
|
return LocationOut{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
r.publishMutationEvent(GID)
|
r.publishMutationEvent(groupID)
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete should only be used after checking that the location is owned by the
|
// delete should only be used after checking that the location is owned by the
|
||||||
// group. Otherwise, use DeleteByGroup
|
// group. Otherwise, use DeleteByGroup
|
||||||
func (r *LocationRepository) delete(ctx context.Context, ID uuid.UUID) error {
|
func (r *LocationRepository) delete(ctx context.Context, locationID uuid.UUID) error {
|
||||||
return r.db.Location.DeleteOneID(ID).Exec(ctx)
|
return r.db.Location.DeleteOneID(locationID).Exec(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) DeleteByGroup(ctx context.Context, GID, ID uuid.UUID) error {
|
func (r *LocationRepository) DeleteByGroup(ctx context.Context, groupID, locationID uuid.UUID) error {
|
||||||
_, err := r.db.Location.Delete().Where(location.ID(ID), location.HasGroupWith(group.ID(GID))).Exec(ctx)
|
_, err := r.db.Location.Delete().Where(location.ID(locationID), location.HasGroupWith(group.ID(groupID))).Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.publishMutationEvent(GID)
|
r.publishMutationEvent(groupID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ type ItemPath struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) PathForLoc(ctx context.Context, GID, locID uuid.UUID) ([]ItemPath, error) {
|
func (r *LocationRepository) PathForLoc(ctx context.Context, groupID, locID uuid.UUID) ([]ItemPath, error) {
|
||||||
query := `WITH RECURSIVE location_path AS (
|
query := `WITH RECURSIVE location_path AS (
|
||||||
SELECT id, name, location_children
|
SELECT id, name, location_children
|
||||||
FROM locations
|
FROM locations
|
||||||
|
@ -290,7 +290,7 @@ func (r *LocationRepository) PathForLoc(ctx context.Context, GID, locID uuid.UUI
|
||||||
SELECT id, name
|
SELECT id, name
|
||||||
FROM location_path`
|
FROM location_path`
|
||||||
|
|
||||||
rows, err := r.db.Sql().QueryContext(ctx, query, locID, GID)
|
rows, err := r.db.Sql().QueryContext(ctx, query, locID, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ func (r *LocationRepository) PathForLoc(ctx context.Context, GID, locID uuid.UUI
|
||||||
return locations, nil
|
return locations, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQuery) ([]TreeItem, error) {
|
func (r *LocationRepository) Tree(ctx context.Context, groupID uuid.UUID, tq TreeQuery) ([]TreeItem, error) {
|
||||||
query := `
|
query := `
|
||||||
WITH recursive location_tree(id, NAME, parent_id, level, node_type) AS
|
WITH recursive location_tree(id, NAME, parent_id, level, node_type) AS
|
||||||
(
|
(
|
||||||
|
@ -402,7 +402,7 @@ func (r *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQue
|
||||||
query = strings.ReplaceAll(query, "{{ WITH_ITEMS_FROM }}", "")
|
query = strings.ReplaceAll(query, "{{ WITH_ITEMS_FROM }}", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := r.db.Sql().QueryContext(ctx, query, GID)
|
rows, err := r.db.Sql().QueryContext(ctx, query, groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,11 +84,11 @@ func mapMaintenanceEntry(entry *ent.MaintenanceEntry) MaintenanceEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *MaintenanceEntryRepository) GetScheduled(ctx context.Context, GID uuid.UUID, dt types.Date) ([]MaintenanceEntry, error) {
|
func (r *MaintenanceEntryRepository) GetScheduled(ctx context.Context, groupID uuid.UUID, dt types.Date) ([]MaintenanceEntry, error) {
|
||||||
entries, err := r.db.MaintenanceEntry.Query().
|
entries, err := r.db.MaintenanceEntry.Query().
|
||||||
Where(
|
Where(
|
||||||
maintenanceentry.HasItemWith(
|
maintenanceentry.HasItemWith(
|
||||||
item.HasGroupWith(group.ID(GID)),
|
item.HasGroupWith(group.ID(groupID)),
|
||||||
),
|
),
|
||||||
maintenanceentry.ScheduledDate(dt.Time()),
|
maintenanceentry.ScheduledDate(dt.Time()),
|
||||||
maintenanceentry.Or(
|
maintenanceentry.Or(
|
||||||
|
@ -97,7 +97,6 @@ func (r *MaintenanceEntryRepository) GetScheduled(ctx context.Context, GID uuid.
|
||||||
),
|
),
|
||||||
).
|
).
|
||||||
All(ctx)
|
All(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -118,8 +117,8 @@ func (r *MaintenanceEntryRepository) Create(ctx context.Context, itemID uuid.UUI
|
||||||
return mapMaintenanceEntryErr(item, err)
|
return mapMaintenanceEntryErr(item, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *MaintenanceEntryRepository) Update(ctx context.Context, ID uuid.UUID, input MaintenanceEntryUpdate) (MaintenanceEntry, error) {
|
func (r *MaintenanceEntryRepository) Update(ctx context.Context, entryID uuid.UUID, input MaintenanceEntryUpdate) (MaintenanceEntry, error) {
|
||||||
item, err := r.db.MaintenanceEntry.UpdateOneID(ID).
|
item, err := r.db.MaintenanceEntry.UpdateOneID(entryID).
|
||||||
SetDate(input.CompletedDate.Time()).
|
SetDate(input.CompletedDate.Time()).
|
||||||
SetScheduledDate(input.ScheduledDate.Time()).
|
SetScheduledDate(input.ScheduledDate.Time()).
|
||||||
SetName(input.Name).
|
SetName(input.Name).
|
||||||
|
@ -202,6 +201,6 @@ FROM
|
||||||
return log, nil
|
return log, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *MaintenanceEntryRepository) Delete(ctx context.Context, ID uuid.UUID) error {
|
func (r *MaintenanceEntryRepository) Delete(ctx context.Context, entryID uuid.UUID) error {
|
||||||
return r.db.MaintenanceEntry.DeleteOneID(ID).Exec(ctx)
|
return r.db.MaintenanceEntry.DeleteOneID(entryID).Exec(ctx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ func TestMaintenanceEntryRepository_GetLog(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.InDelta(t, total, log.CostTotal, .001, "total cost should be equal to the sum of all entries")
|
assert.InDelta(t, total, log.CostTotal, .001, "total cost should be equal to the sum of all entries")
|
||||||
assert.InDelta(t, total/2, log.CostAverage, 001, "average cost should be the average of the two months")
|
assert.InDelta(t, total/2, log.CostAverage, 0o01, "average cost should be the average of the two months")
|
||||||
|
|
||||||
for _, entry := range log.Entries {
|
for _, entry := range log.Entries {
|
||||||
err := tRepos.MaintEntry.Delete(context.Background(), entry.ID)
|
err := tRepos.MaintEntry.Delete(context.Background(), entry.ID)
|
||||||
|
|
|
@ -114,7 +114,7 @@ func (r *NotifierRepository) Update(ctx context.Context, userID uuid.UUID, id uu
|
||||||
return r.mapper.MapErr(notifier, err)
|
return r.mapper.MapErr(notifier, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *NotifierRepository) Delete(ctx context.Context, userID uuid.UUID, ID uuid.UUID) error {
|
func (r *NotifierRepository) Delete(ctx context.Context, userID uuid.UUID, notifierID uuid.UUID) error {
|
||||||
_, err := r.db.Notifier.Delete().Where(notifier.UserID(userID), notifier.ID(ID)).Exec(ctx)
|
_, err := r.db.Notifier.Delete().Where(notifier.UserID(userID), notifier.ID(notifierID)).Exec(ctx)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||||
|
"github.com/hay-kot/homebox/backend/internal/data/ent/actiontoken"
|
||||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,9 +61,9 @@ func mapUserOut(user *ent.User) UserOut {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UserRepository) GetOneID(ctx context.Context, ID uuid.UUID) (UserOut, error) {
|
func (r *UserRepository) GetOneID(ctx context.Context, userID uuid.UUID) (UserOut, error) {
|
||||||
return mapUserOutErr(r.db.User.Query().
|
return mapUserOutErr(r.db.User.Query().
|
||||||
Where(user.ID(ID)).
|
Where(user.ID(userID)).
|
||||||
WithGroup().
|
WithGroup().
|
||||||
Only(ctx))
|
Only(ctx))
|
||||||
}
|
}
|
||||||
|
@ -101,9 +102,9 @@ func (r *UserRepository) Create(ctx context.Context, usr UserCreate) (UserOut, e
|
||||||
return r.GetOneID(ctx, entUser.ID)
|
return r.GetOneID(ctx, entUser.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UserRepository) Update(ctx context.Context, ID uuid.UUID, data UserUpdate) error {
|
func (r *UserRepository) Update(ctx context.Context, userID uuid.UUID, data UserUpdate) error {
|
||||||
q := r.db.User.Update().
|
q := r.db.User.Update().
|
||||||
Where(user.ID(ID)).
|
Where(user.ID(userID)).
|
||||||
SetName(data.Name).
|
SetName(data.Name).
|
||||||
SetEmail(data.Email)
|
SetEmail(data.Email)
|
||||||
|
|
||||||
|
@ -130,6 +131,28 @@ func (r *UserRepository) GetSuperusers(ctx context.Context) ([]*ent.User, error)
|
||||||
return users, nil
|
return users, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *UserRepository) ChangePassword(ctx context.Context, UID uuid.UUID, pw string) error {
|
func (r *UserRepository) ChangePassword(ctx context.Context, userID uuid.UUID, pw string) error {
|
||||||
return r.db.User.UpdateOneID(UID).SetPassword(pw).Exec(ctx)
|
return r.db.User.UpdateOneID(userID).SetPassword(pw).Exec(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserRepository) PasswordResetCreate(ctx context.Context, userID uuid.UUID, token []byte) error {
|
||||||
|
return r.db.ActionToken.Create().
|
||||||
|
SetUserID(userID).
|
||||||
|
SetToken(token).
|
||||||
|
SetAction(actiontoken.ActionResetPassword).
|
||||||
|
Exec(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserRepository) PasswordResetGet(ctx context.Context, token []byte) (*ent.ActionToken, error) {
|
||||||
|
return r.db.ActionToken.Query().
|
||||||
|
Where(actiontoken.Token(token)).
|
||||||
|
WithUser().
|
||||||
|
Only(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserRepository) PasswordResetDelete(ctx context.Context, token []byte) error {
|
||||||
|
_, err := r.db.ActionToken.Delete().
|
||||||
|
Where(actiontoken.Token(token)).
|
||||||
|
Exec(ctx)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,14 @@ const (
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
conf.Version
|
conf.Version
|
||||||
Mode string `yaml:"mode" conf:"default:development"` // development or production
|
Mode string `yaml:"mode" conf:"default:development"` // development or production
|
||||||
Web WebConfig `yaml:"web"`
|
Web WebConfig `yaml:"web"`
|
||||||
Storage Storage `yaml:"storage"`
|
Storage Storage `yaml:"storage"`
|
||||||
Log LoggerConf `yaml:"logger"`
|
Log LoggerConf `yaml:"logger"`
|
||||||
Mailer MailerConf `yaml:"mailer"`
|
Mailer MailerConf `yaml:"mailer"`
|
||||||
Demo bool `yaml:"demo"`
|
Demo bool `yaml:"demo"`
|
||||||
Debug DebugConf `yaml:"debug"`
|
Debug DebugConf `yaml:"debug"`
|
||||||
|
BaseURL string `yaml:"base_url" conf:"default:http://localhost:3000"`
|
||||||
Options Options `yaml:"options"`
|
Options Options `yaml:"options"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ type MailerConf struct {
|
||||||
Port int `conf:""`
|
Port int `conf:""`
|
||||||
Username string `conf:""`
|
Username string `conf:""`
|
||||||
Password string `conf:""`
|
Password string `conf:""`
|
||||||
From string `conf:""`
|
From string `conf:"info@example.com"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ready is a simple check to ensure that the configuration is not empty.
|
// Ready is a simple check to ensure that the configuration is not empty.
|
||||||
// or with it's default state.
|
// or with it's default state.
|
||||||
func (mc *MailerConf) Ready() bool {
|
func (mc *MailerConf) Ready() bool {
|
||||||
return mc.Host != "" && mc.Port != 0 && mc.Username != "" && mc.Password != "" && mc.From != ""
|
return mc.Host != "" && mc.Port != 0 && mc.From != ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UnauthorizedError struct {
|
type UnauthorizedError struct{}
|
||||||
}
|
|
||||||
|
|
||||||
func (err *UnauthorizedError) Error() string {
|
func (err *UnauthorizedError) Error() string {
|
||||||
return "unauthorized"
|
return "unauthorized"
|
||||||
|
|
|
@ -49,7 +49,6 @@ func init() { // nolint
|
||||||
|
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AdapterFunc[T any, Y any] func(*http.Request, T) (Y, error)
|
type (
|
||||||
type IDFunc[T any, Y any] func(*http.Request, uuid.UUID, T) (Y, error)
|
AdapterFunc[T any, Y any] func(*http.Request, T) (Y, error)
|
||||||
|
IDFunc[T any, Y any] func(*http.Request, uuid.UUID, T) (Y, error)
|
||||||
|
)
|
||||||
|
|
|
@ -8,8 +8,10 @@ import (
|
||||||
"github.com/hay-kot/httpkit/server"
|
"github.com/hay-kot/httpkit/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CommandFunc[T any] func(*http.Request) (T, error)
|
type (
|
||||||
type CommandIDFunc[T any] func(*http.Request, uuid.UUID) (T, error)
|
CommandFunc[T any] func(*http.Request) (T, error)
|
||||||
|
CommandIDFunc[T any] func(*http.Request, uuid.UUID) (T, error)
|
||||||
|
)
|
||||||
|
|
||||||
// Command is an HandlerAdapter that returns a errchain.HandlerFunc that
|
// Command is an HandlerAdapter that returns a errchain.HandlerFunc that
|
||||||
// The command adapters are used to handle commands that do not accept a body
|
// The command adapters are used to handle commands that do not accept a body
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Package mailer provides a simple mailer for sending emails.
|
// Package mailer provides a simple interface to send emails using SMTP.
|
||||||
package mailer
|
package mailer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -25,16 +25,16 @@ func (m *Mailer) server() string {
|
||||||
return m.Host + ":" + strconv.Itoa(m.Port)
|
return m.Host + ":" + strconv.Itoa(m.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mailer) Send(msg *Message) error {
|
func (m *Mailer) Send(msg Message) error {
|
||||||
server := m.server()
|
server := m.server()
|
||||||
|
|
||||||
header := make(map[string]string)
|
header := map[string]string{
|
||||||
header["From"] = msg.From.String()
|
"From": m.From,
|
||||||
header["To"] = msg.To.String()
|
"Subject": mime.QEncoding.Encode("UTF-8", msg.Subject),
|
||||||
header["Subject"] = mime.QEncoding.Encode("UTF-8", msg.Subject)
|
"MIME-Version": "1.0",
|
||||||
header["MIME-Version"] = "1.0"
|
"Content-Type": "text/html; charset=\"utf-8\"",
|
||||||
header["Content-Type"] = "text/html; charset=\"utf-8\""
|
"Content-Transfer-Encoding": "base64",
|
||||||
header["Content-Transfer-Encoding"] = "base64"
|
}
|
||||||
|
|
||||||
message := ""
|
message := ""
|
||||||
for k, v := range header {
|
for k, v := range header {
|
||||||
|
@ -46,7 +46,7 @@ func (m *Mailer) Send(msg *Message) error {
|
||||||
server,
|
server,
|
||||||
smtp.PlainAuth("", m.Username, m.Password, m.Host),
|
smtp.PlainAuth("", m.Username, m.Password, m.Host),
|
||||||
m.From,
|
m.From,
|
||||||
[]string{msg.To.Address},
|
msg.ToAddresses(),
|
||||||
[]byte(message),
|
[]byte(message),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ func GetTestMailer() (*Mailer, error) {
|
||||||
|
|
||||||
// Unmarshal JSON
|
// Unmarshal JSON
|
||||||
err = json.Unmarshal(bytes, mailer)
|
err = json.Unmarshal(bytes, mailer)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@ type Message struct {
|
||||||
Body string
|
Body string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Message) ToAddresses() []string {
|
||||||
|
return []string{m.To.Address}
|
||||||
|
}
|
||||||
|
|
||||||
type MessageBuilder struct {
|
type MessageBuilder struct {
|
||||||
subject string
|
subject string
|
||||||
to mail.Address
|
to mail.Address
|
||||||
|
@ -20,8 +24,8 @@ func NewMessageBuilder() *MessageBuilder {
|
||||||
return &MessageBuilder{}
|
return &MessageBuilder{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mb *MessageBuilder) Build() *Message {
|
func (mb *MessageBuilder) Build() Message {
|
||||||
return &Message{
|
return Message{
|
||||||
Subject: mb.subject,
|
Subject: mb.subject,
|
||||||
To: mb.to,
|
To: mb.to,
|
||||||
From: mb.from,
|
From: mb.from,
|
||||||
|
|
|
@ -48,7 +48,6 @@ func render(tpl string, data TemplateProps) (string, error) {
|
||||||
var tplBuffer bytes.Buffer
|
var tplBuffer bytes.Buffer
|
||||||
|
|
||||||
err = tmpl.Execute(&tplBuffer, data)
|
err = tmpl.Execute(&tplBuffer, data)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1785,6 +1785,33 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/users/request-password-reset": {
|
||||||
|
"post": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"User"
|
||||||
|
],
|
||||||
|
"summary": "Request Password Reset",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "User Data",
|
||||||
|
"name": "payload",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/services.PasswordResetRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/users/self": {
|
"/v1/users/self": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
@ -2818,6 +2845,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"services.PasswordResetRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"services.UserRegistration": {
|
"services.UserRegistration": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
ignorePatterns: ["nuxt.proxyoverride.ts"],
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
es2021: true,
|
es2021: true,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { useId } from "./use-ids";
|
|
||||||
|
|
||||||
interface Notification {
|
interface Notification {
|
||||||
id: string;
|
id: string;
|
||||||
message: string;
|
message: string;
|
||||||
|
|
66
frontend/layouts/center-card.vue
Normal file
66
frontend/layouts/center-card.vue
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import MdiGithub from "~icons/mdi/github";
|
||||||
|
import MdiTwitter from "~icons/mdi/twitter";
|
||||||
|
import MdiDiscord from "~icons/mdi/discord";
|
||||||
|
import MdiFolder from "~icons/mdi/folder";
|
||||||
|
|
||||||
|
const api = usePublicApi();
|
||||||
|
|
||||||
|
const { data: status } = useAsyncData(async () => {
|
||||||
|
const { data } = await api.status();
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<AppToast />
|
||||||
|
<div class="flex flex-col min-h-screen">
|
||||||
|
<div class="fill-primary min-w-full absolute top-0 z-[-1]">
|
||||||
|
<div class="bg-primary flex-col flex min-h-[20vh]" />
|
||||||
|
<svg
|
||||||
|
class="fill-primary drop-shadow-xl"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 1440 320"
|
||||||
|
preserveAspectRatio="none"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-opacity="1"
|
||||||
|
d="M0,32L80,69.3C160,107,320,181,480,181.3C640,181,800,107,960,117.3C1120,128,1280,224,1360,272L1440,320L1440,0L1360,0C1280,0,1120,0,960,0C800,0,640,0,480,0C320,0,160,0,80,0L0,0Z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<header class="p-4 sm:px-6 lg:p-14 sm:py-6 sm:flex sm:items-end mx-auto">
|
||||||
|
<div>
|
||||||
|
<h2 class="mt-1 text-4xl font-bold tracking-tight text-neutral-content sm:text-5xl lg:text-6xl flex">
|
||||||
|
HomeB
|
||||||
|
<AppLogo class="w-12 -mb-4" />
|
||||||
|
x
|
||||||
|
</h2>
|
||||||
|
<p class="ml-1 text-lg text-base-content/50">Track, Organize, and Manage your Things.</p>
|
||||||
|
</div>
|
||||||
|
<div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content">
|
||||||
|
<a class="tooltip" data-tip="Project Github" href="https://github.com/hay-kot/homebox" target="_blank">
|
||||||
|
<MdiGithub class="h-8 w-8" />
|
||||||
|
</a>
|
||||||
|
<a href="https://twitter.com/haybytes" class="tooltip" data-tip="Follow The Developer" target="_blank">
|
||||||
|
<MdiTwitter class="h-8 w-8" />
|
||||||
|
</a>
|
||||||
|
<a href="https://discord.gg/tuncmNrE4z" class="tooltip" data-tip="Join The Discord" target="_blank">
|
||||||
|
<MdiDiscord class="h-8 w-8" />
|
||||||
|
</a>
|
||||||
|
<a href="https://hay-kot.github.io/homebox/" class="tooltip" data-tip="Read The Docs" target="_blank">
|
||||||
|
<MdiFolder class="h-8 w-8" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="grid p-6 sm:place-items-center min-h-[50vh]">
|
||||||
|
<slot :status="status" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer v-if="status" class="mt-auto text-center w-full bottom-0 pb-4">
|
||||||
|
<p class="text-center text-sm">Version: {{ status.build.version }} ~ Build: {{ status.build.commit }}</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -1,4 +1,3 @@
|
||||||
<script setup lang="ts"></script>
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<AppToast />
|
<AppToast />
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import { BaseAPI, route } from "./base";
|
import { BaseAPI, route } from "./base";
|
||||||
import type { APISummary, LoginForm, TokenResponse, UserRegistration } from "./types/data-contracts";
|
import type {
|
||||||
|
APISummary,
|
||||||
|
LoginForm,
|
||||||
|
PasswordResetRequest,
|
||||||
|
TokenResponse,
|
||||||
|
UserRegistration,
|
||||||
|
} from "./types/data-contracts";
|
||||||
|
|
||||||
export type StatusResult = {
|
export type StatusResult = {
|
||||||
health: boolean;
|
health: boolean;
|
||||||
|
@ -27,4 +33,11 @@ export class PublicApi extends BaseAPI {
|
||||||
public register(body: UserRegistration) {
|
public register(body: UserRegistration) {
|
||||||
return this.http.post<UserRegistration, TokenResponse>({ url: route("/users/register"), body });
|
return this.http.post<UserRegistration, TokenResponse>({ url: route("/users/register"), body });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public resetPasseord(email: string) {
|
||||||
|
return this.http.post<PasswordResetRequest, void>({
|
||||||
|
url: route("/users/request-password-reset"),
|
||||||
|
body: { email },
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,6 +373,10 @@ export interface ValueOverTimeEntry {
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PasswordResetRequest {
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserRegistration {
|
export interface UserRegistration {
|
||||||
email: string;
|
email: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { defineNuxtModule, logger } from "@nuxt/kit";
|
||||||
//
|
//
|
||||||
// fix from
|
// fix from
|
||||||
// - https://gist.github.com/ucw/67f7291c64777fb24341e8eae72bcd24
|
// - https://gist.github.com/ucw/67f7291c64777fb24341e8eae72bcd24
|
||||||
// eslint-disable-next-line
|
|
||||||
import { createProxyServer } from "http-proxy";
|
import { createProxyServer } from "http-proxy";
|
||||||
|
|
||||||
export default defineNuxtModule({
|
export default defineNuxtModule({
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"@faker-js/faker": "^8.0.0",
|
"@faker-js/faker": "^8.0.0",
|
||||||
"@iconify-json/mdi": "^1.1.64",
|
"@iconify-json/mdi": "^1.1.64",
|
||||||
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
"@nuxtjs/eslint-config-typescript": "^12.0.0",
|
||||||
|
"@nuxtjs/tailwindcss": "^6.12.0",
|
||||||
"@types/dompurify": "^3.0.0",
|
"@types/dompurify": "^3.0.0",
|
||||||
"@types/markdown-it": "^13.0.0",
|
"@types/markdown-it": "^13.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||||
|
@ -28,7 +29,7 @@
|
||||||
"eslint-plugin-vue": "^9.4.0",
|
"eslint-plugin-vue": "^9.4.0",
|
||||||
"h3": "^1.7.1",
|
"h3": "^1.7.1",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"nuxt": "3.6.5",
|
"nuxt": "3.11.2",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"unplugin-icons": "^0.18.5",
|
"unplugin-icons": "^0.18.5",
|
||||||
|
@ -37,7 +38,6 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/vue": "^1.7.9",
|
"@headlessui/vue": "^1.7.9",
|
||||||
"@nuxtjs/tailwindcss": "^6.1.3",
|
|
||||||
"@pinia/nuxt": "^0.5.0",
|
"@pinia/nuxt": "^0.5.0",
|
||||||
"@tailwindcss/aspect-ratio": "^0.4.0",
|
"@tailwindcss/aspect-ratio": "^0.4.0",
|
||||||
"@tailwindcss/forms": "^0.5.2",
|
"@tailwindcss/forms": "^0.5.2",
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import MdiGithub from "~icons/mdi/github";
|
import { useRouteHash } from "@vueuse/router";
|
||||||
import MdiTwitter from "~icons/mdi/twitter";
|
|
||||||
import MdiDiscord from "~icons/mdi/discord";
|
|
||||||
import MdiFolder from "~icons/mdi/folder";
|
|
||||||
import MdiAccount from "~icons/mdi/account";
|
import MdiAccount from "~icons/mdi/account";
|
||||||
import MdiAccountPlus from "~icons/mdi/account-plus";
|
import MdiAccountPlus from "~icons/mdi/account-plus";
|
||||||
import MdiLogin from "~icons/mdi/login";
|
import MdiLogin from "~icons/mdi/login";
|
||||||
import MdiArrowRight from "~icons/mdi/arrow-right";
|
import MdiArrowRight from "~icons/mdi/arrow-right";
|
||||||
import MdiLock from "~icons/mdi/lock";
|
import MdiLock from "~icons/mdi/lock";
|
||||||
|
|
||||||
|
enum PageForms {
|
||||||
|
Register = "register",
|
||||||
|
Login = "login",
|
||||||
|
ForgotPassword = "forgot-password",
|
||||||
|
}
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: "Homebox | Organize and Tag Your Stuff",
|
title: "Homebox | Organize and Tag Your Stuff",
|
||||||
});
|
});
|
||||||
|
@ -30,21 +33,13 @@
|
||||||
const api = usePublicApi();
|
const api = usePublicApi();
|
||||||
const toast = useNotifier();
|
const toast = useNotifier();
|
||||||
|
|
||||||
const { data: status } = useAsyncData(async () => {
|
const pageForm = useRouteHash(PageForms.Login);
|
||||||
const { data } = await api.status();
|
const pageFormStr = computed(() => {
|
||||||
|
if (!pageForm.value) {
|
||||||
if (data.demo) {
|
return PageForms.Login;
|
||||||
username.value = "demo@example.com";
|
|
||||||
password.value = "demo";
|
|
||||||
}
|
}
|
||||||
return data;
|
|
||||||
});
|
|
||||||
|
|
||||||
whenever(status, status => {
|
return pageForm.value[0] === "#" ? pageForm.value.slice(1) : pageForm.value;
|
||||||
if (status?.demo) {
|
|
||||||
email.value = "demo@example.com";
|
|
||||||
loginPassword.value = "demo";
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -92,12 +87,12 @@
|
||||||
toast.success("User registered");
|
toast.success("User registered");
|
||||||
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
registerForm.value = false;
|
pageForm.value = PageForms.Login;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (groupToken.value !== "") {
|
if (groupToken.value !== "") {
|
||||||
registerForm.value = true;
|
pageForm.value = PageForms.Register;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -120,139 +115,134 @@
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [registerForm, toggleLogin] = useToggle();
|
async function resetPassword() {
|
||||||
|
if (email.value === "") {
|
||||||
|
toast.error("Email is required");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resp = await api.resetPasseord(email.value);
|
||||||
|
if (resp.error) {
|
||||||
|
toast.error("Problem resetting password");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.success("Password reset link sent to your email");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col min-h-screen">
|
<NuxtLayout v-slot="{ status }" name="center-card">
|
||||||
<div class="fill-primary min-w-full absolute top-0 z-[-1]">
|
|
||||||
<div class="bg-primary flex-col flex min-h-[20vh]" />
|
|
||||||
<svg
|
|
||||||
class="fill-primary drop-shadow-xl"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 1440 320"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill-opacity="1"
|
|
||||||
d="M0,32L80,69.3C160,107,320,181,480,181.3C640,181,800,107,960,117.3C1120,128,1280,224,1360,272L1440,320L1440,0L1360,0C1280,0,1120,0,960,0C800,0,640,0,480,0C320,0,160,0,80,0L0,0Z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<header class="p-4 sm:px-6 lg:p-14 sm:py-6 sm:flex sm:items-end mx-auto">
|
<Transition name="slide-fade">
|
||||||
<div>
|
<form v-if="pageFormStr === PageForms.Register" @submit.prevent="registerUser">
|
||||||
<h2 class="mt-1 text-4xl font-bold tracking-tight text-neutral-content sm:text-5xl lg:text-6xl flex">
|
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||||
HomeB
|
<div class="card-body">
|
||||||
<AppLogo class="w-12 -mb-4" />
|
<h2 class="card-title text-2xl align-center">
|
||||||
x
|
<MdiAccount class="mr-1 w-7 h-7" />
|
||||||
</h2>
|
Register
|
||||||
<p class="ml-1 text-lg text-base-content/50">Track, Organize, and Manage your Things.</p>
|
</h2>
|
||||||
</div>
|
<FormTextField v-model="email" label="Set your email?" />
|
||||||
<div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content">
|
<FormTextField v-model="username" label="What's your name?" />
|
||||||
<a class="tooltip" data-tip="Project Github" href="https://github.com/hay-kot/homebox" target="_blank">
|
<div v-if="!(groupToken == '')" class="pt-4 pb-1 text-center">
|
||||||
<MdiGithub class="h-8 w-8" />
|
<p>You're Joining an Existing Group!</p>
|
||||||
</a>
|
<button type="button" class="text-xs underline" @click="groupToken = ''">
|
||||||
<a href="https://twitter.com/haybytes" class="tooltip" data-tip="Follow The Developer" target="_blank">
|
Don't Want To Join a Group?
|
||||||
<MdiTwitter class="h-8 w-8" />
|
</button>
|
||||||
</a>
|
|
||||||
<a href="https://discord.gg/tuncmNrE4z" class="tooltip" data-tip="Join The Discord" target="_blank">
|
|
||||||
<MdiDiscord class="h-8 w-8" />
|
|
||||||
</a>
|
|
||||||
<a href="https://hay-kot.github.io/homebox/" class="tooltip" data-tip="Read The Docs" target="_blank">
|
|
||||||
<MdiFolder class="h-8 w-8" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="grid p-6 sm:place-items-center min-h-[50vh]">
|
|
||||||
<div>
|
|
||||||
<Transition name="slide-fade">
|
|
||||||
<form v-if="registerForm" @submit.prevent="registerUser">
|
|
||||||
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
|
||||||
<div class="card-body">
|
|
||||||
<h2 class="card-title text-2xl align-center">
|
|
||||||
<MdiAccount class="mr-1 w-7 h-7" />
|
|
||||||
Register
|
|
||||||
</h2>
|
|
||||||
<FormTextField v-model="email" label="Set your email?" />
|
|
||||||
<FormTextField v-model="username" label="What's your name?" />
|
|
||||||
<div v-if="!(groupToken == '')" class="pt-4 pb-1 text-center">
|
|
||||||
<p>You're Joining an Existing Group!</p>
|
|
||||||
<button type="button" class="text-xs underline" @click="groupToken = ''">
|
|
||||||
Don't Want To Join a Group?
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<FormPassword v-model="password" label="Set your password" />
|
|
||||||
<PasswordScore v-model:valid="canRegister" :password="password" />
|
|
||||||
<div class="card-actions justify-end">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary mt-2"
|
|
||||||
:class="loading ? 'loading' : ''"
|
|
||||||
:disabled="loading || !canRegister"
|
|
||||||
>
|
|
||||||
Register
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
<FormPassword v-model="password" label="Set your password" />
|
||||||
<form v-else @submit.prevent="login">
|
<PasswordScore v-model:valid="canRegister" :password="password" />
|
||||||
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
<div class="card-actions justify-end">
|
||||||
<div class="card-body">
|
<button
|
||||||
<h2 class="card-title text-2xl align-center">
|
type="submit"
|
||||||
<MdiAccount class="mr-1 w-7 h-7" />
|
class="btn btn-primary mt-2"
|
||||||
Login
|
:class="loading ? 'loading' : ''"
|
||||||
</h2>
|
:disabled="loading || !canRegister"
|
||||||
<template v-if="status && status.demo">
|
>
|
||||||
<p class="text-xs italic text-center">This is a demo instance</p>
|
Register
|
||||||
<p class="text-xs text-center"><b>Email</b> demo@example.com</p>
|
</button>
|
||||||
<p class="text-xs text-center"><b>Password</b> demo</p>
|
|
||||||
</template>
|
|
||||||
<FormTextField v-model="email" label="Email" />
|
|
||||||
<FormPassword v-model="loginPassword" label="Password" />
|
|
||||||
<div class="max-w-[140px]">
|
|
||||||
<FormCheckbox v-model="remember" label="Remember Me" />
|
|
||||||
</div>
|
|
||||||
<div class="card-actions justify-end">
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
class="btn btn-primary btn-block"
|
|
||||||
:class="loading ? 'loading' : ''"
|
|
||||||
:disabled="loading"
|
|
||||||
>
|
|
||||||
Login
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</Transition>
|
|
||||||
<div class="text-center mt-6">
|
|
||||||
<BaseButton
|
|
||||||
v-if="status && status.allowRegistration"
|
|
||||||
class="btn-primary btn-wide"
|
|
||||||
@click="() => toggleLogin()"
|
|
||||||
>
|
|
||||||
<template #icon>
|
|
||||||
<MdiAccountPlus v-if="!registerForm" class="w-5 h-5 swap-off" />
|
|
||||||
<MdiLogin v-else class="w-5 h-5 swap-off" />
|
|
||||||
<MdiArrowRight class="w-5 h-5 swap-on" />
|
|
||||||
</template>
|
|
||||||
{{ registerForm ? "Login" : "Register" }}
|
|
||||||
</BaseButton>
|
|
||||||
<p v-else class="text-base-content italic text-sm inline-flex items-center gap-2">
|
|
||||||
<MdiLock class="w-4 h-4 inline-block" />
|
|
||||||
Registration Disabled
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
|
<form v-else-if="pageFormStr === PageForms.ForgotPassword" @submit.prevent="resetPassword">
|
||||||
|
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2 class="card-title text-2xl align-center">
|
||||||
|
<MdiAccount class="mr-1 w-7 h-7" />
|
||||||
|
Reset Password
|
||||||
|
</h2>
|
||||||
|
<FormTextField v-model="email" label="Email" />
|
||||||
|
<p class="text-sm text-base-content/50">
|
||||||
|
If you have an account with us, we will send you a password reset link.
|
||||||
|
</p>
|
||||||
|
<div class="card-actions justify-end mt-4">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
:class="loading ? 'loading' : ''"
|
||||||
|
:disabled="loading"
|
||||||
|
>
|
||||||
|
Reset Password
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form v-else @submit.prevent="login">
|
||||||
|
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2 class="card-title text-2xl align-center">
|
||||||
|
<MdiAccount class="mr-1 w-7 h-7" />
|
||||||
|
Login
|
||||||
|
</h2>
|
||||||
|
<template v-if="status && status.demo">
|
||||||
|
<p class="text-xs italic text-center">This is a demo instance</p>
|
||||||
|
<p class="text-xs text-center"><b>Email</b> demo@example.com</p>
|
||||||
|
<p class="text-xs text-center"><b>Password</b> demo</p>
|
||||||
|
</template>
|
||||||
|
<FormTextField v-model="email" label="Email" />
|
||||||
|
<FormPassword v-model="loginPassword" label="Password" />
|
||||||
|
<div class="max-w-[140px]">
|
||||||
|
<FormCheckbox v-model="remember" label="Remember Me" />
|
||||||
|
</div>
|
||||||
|
<div class="card-actions justify-end">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
:class="loading ? 'loading' : ''"
|
||||||
|
:disabled="loading"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Transition>
|
||||||
|
<div class="text-center mt-6">
|
||||||
|
<BaseButton
|
||||||
|
v-if="status && status.allowRegistration"
|
||||||
|
class="btn-primary btn-wide"
|
||||||
|
:to="pageFormStr === PageForms.Register ? `#${PageForms.Login}` : `#${PageForms.Register}`"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<MdiAccountPlus v-if="pageFormStr === PageForms.Register" class="w-5 h-5 swap-off" />
|
||||||
|
<MdiLogin v-else class="w-5 h-5 swap-off" />
|
||||||
|
<MdiArrowRight class="w-5 h-5 swap-on" />
|
||||||
|
</template>
|
||||||
|
{{ pageFormStr === PageForms.Register ? "Login" : "Register" }}
|
||||||
|
</BaseButton>
|
||||||
|
<p v-else class="text-base-content italic text-sm inline-flex items-center gap-2">
|
||||||
|
<MdiLock class="w-4 h-4 inline-block" />
|
||||||
|
Registration Disabled
|
||||||
|
</p>
|
||||||
|
<NuxtLink :to="`#${PageForms.ForgotPassword}`">
|
||||||
|
<p class="text-xs text-base-content/50 mt-2">Forgot your password?</p>
|
||||||
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer v-if="status" class="mt-auto text-center w-full bottom-0 pb-4">
|
</NuxtLayout>
|
||||||
<p class="text-center text-sm">Version: {{ status.build.version }} ~ Build: {{ status.build.commit }}</p>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
|
|
74
frontend/pages/reset-password.vue
Normal file
74
frontend/pages/reset-password.vue
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Title>Password Reset</Title>
|
||||||
|
<form @submit.prevent="resetPassword">
|
||||||
|
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||||
|
<div class="card-body">
|
||||||
|
<h2 class="card-title text-2xl align-center">
|
||||||
|
<MdiAccount class="mr-1 w-7 h-7" />
|
||||||
|
Password Reset
|
||||||
|
</h2>
|
||||||
|
<FormPassword v-model="form.password" label="New Password" />
|
||||||
|
<FormPassword v-model="form.passwordConfirm" label="Confirm Password" />
|
||||||
|
<PasswordScore v-model:valid="form.requirementsMet" :password="form.password" />
|
||||||
|
<div class="card-actions justify-end">
|
||||||
|
<button type="submit" class="btn btn-primary mt-2" :class="loading ? 'loading' : ''">Reset Password</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="grid place-content-center pt-4">
|
||||||
|
<NuxtLink to="/#login">
|
||||||
|
<p class="text-xs text-base-content/50 mt-2">Account Login</p>
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import MdiAccount from "~icons/mdi/account";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
|
||||||
|
definePageMeta({
|
||||||
|
title: "Password Reset",
|
||||||
|
layout: "center-card",
|
||||||
|
middleware: [
|
||||||
|
() => {
|
||||||
|
const ctx = useAuthContext();
|
||||||
|
if (ctx.isAuthorized()) {
|
||||||
|
return "/home";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const toast = useNotifier();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const token = route.query.token;
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
requirementsMet: false,
|
||||||
|
password: "",
|
||||||
|
passwordConfirm: "",
|
||||||
|
});
|
||||||
|
function resetPassword() {
|
||||||
|
if (token === undefined) {
|
||||||
|
return toast.error("Invalid reset token");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.password !== form.passwordConfirm) {
|
||||||
|
return toast.error("Passwords do not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!form.requirementsMet) {
|
||||||
|
return toast.error("Password does not meet requirements");
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
16882
frontend/pnpm-lock.yaml
generated
16882
frontend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue