From 97524b1ffef58f1d3405b76fed4f023046f45625 Mon Sep 17 00:00:00 2001 From: yokowu <18836617@qq.com> Date: Wed, 16 Jul 2025 18:32:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(user):=20=E8=AE=B0=E5=BD=95=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=8E=86=E5=8F=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitattributes | 1 + backend/cmd/server/wire_gen.go | 7 +- backend/consts/os.go | 17 + backend/db/admin/admin.go | 2 +- backend/db/admin_query.go | 13 +- backend/db/adminloginhistory.go | 14 +- .../db/adminloginhistory/adminloginhistory.go | 13 +- backend/db/adminloginhistory/where.go | 62 ++- backend/db/adminloginhistory_create.go | 161 ++++++- backend/db/adminloginhistory_query.go | 18 +- backend/db/adminloginhistory_update.go | 90 +++- backend/db/migrate/schema.go | 28 +- backend/db/mutation.go | 424 ++++++++++++++++-- backend/db/runtime/runtime.go | 2 +- backend/db/user/user.go | 2 +- backend/db/user_query.go | 13 +- backend/db/userloginhistory.go | 53 ++- .../db/userloginhistory/userloginhistory.go | 41 +- backend/db/userloginhistory/where.go | 347 +++++++++++--- backend/db/userloginhistory_create.go | 366 +++++++++++++-- backend/db/userloginhistory_query.go | 18 +- backend/db/userloginhistory_update.go | 231 +++++++++- backend/domain/ip.go | 8 + backend/domain/oauth.go | 1 + backend/domain/user.go | 29 +- backend/ent/schema/adminloginhistory.go | 12 +- backend/ent/schema/userloginhistory.go | 16 +- backend/go.mod | 1 + backend/go.sum | 2 + backend/internal/user/handler/v1/user.go | 3 + backend/internal/user/repo/user.go | 57 ++- backend/internal/user/usecase/user.go | 29 +- ..._alter_user_login_histories_table.down.sql | 0 ...08_alter_user_login_histories_table.up.sql | 5 + backend/pkg/ipdb/ip2region.xdb | 3 + backend/pkg/ipdb/ipdb.go | 61 +++ backend/pkg/provider.go | 2 + 37 files changed, 1792 insertions(+), 360 deletions(-) create mode 100644 .gitattributes create mode 100644 backend/consts/os.go create mode 100644 backend/domain/ip.go create mode 100644 backend/migration/000008_alter_user_login_histories_table.down.sql create mode 100644 backend/migration/000008_alter_user_login_histories_table.up.sql create mode 100644 backend/pkg/ipdb/ip2region.xdb create mode 100644 backend/pkg/ipdb/ipdb.go diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..99ca423 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.xdb filter=lfs diff=lfs merge=lfs -text diff --git a/backend/cmd/server/wire_gen.go b/backend/cmd/server/wire_gen.go index d757e09..7c6ce00 100644 --- a/backend/cmd/server/wire_gen.go +++ b/backend/cmd/server/wire_gen.go @@ -32,6 +32,7 @@ import ( repo5 "github.com/chaitin/MonkeyCode/backend/internal/user/repo" usecase4 "github.com/chaitin/MonkeyCode/backend/internal/user/usecase" "github.com/chaitin/MonkeyCode/backend/pkg" + "github.com/chaitin/MonkeyCode/backend/pkg/ipdb" "github.com/chaitin/MonkeyCode/backend/pkg/logger" "github.com/chaitin/MonkeyCode/backend/pkg/session" "github.com/chaitin/MonkeyCode/backend/pkg/store" @@ -68,7 +69,11 @@ func newServer() (*Server, error) { sessionSession := session.NewSession(configConfig) authMiddleware := middleware.NewAuthMiddleware(sessionSession, slogLogger) modelHandler := v1_2.NewModelHandler(web, modelUsecase, authMiddleware, slogLogger) - userRepo := repo5.NewUserRepo(client) + ipdbIPDB, err := ipdb.NewIPDB(slogLogger) + if err != nil { + return nil, err + } + userRepo := repo5.NewUserRepo(client, ipdbIPDB) userUsecase := usecase4.NewUserUsecase(configConfig, redisClient, userRepo, slogLogger) userHandler := v1_3.NewUserHandler(web, userUsecase, extensionUsecase, authMiddleware, sessionSession, slogLogger, configConfig) dashboardRepo := repo6.NewDashboardRepo(client) diff --git a/backend/consts/os.go b/backend/consts/os.go new file mode 100644 index 0000000..023cc26 --- /dev/null +++ b/backend/consts/os.go @@ -0,0 +1,17 @@ +package consts + +import "strings" + +type OSType string + +func (o OSType) Name() string { + if strings.HasPrefix(string(o), "Windows") { + return "Windows" + } + if strings.HasPrefix(string(o), "Darwin") { + return "MacOS" + } + return string(o) +} + +type OSRelease string diff --git a/backend/db/admin/admin.go b/backend/db/admin/admin.go index 823d8d9..d89672a 100644 --- a/backend/db/admin/admin.go +++ b/backend/db/admin/admin.go @@ -36,7 +36,7 @@ const ( // It exists in this package in order to avoid circular dependency with the "adminloginhistory" package. LoginHistoriesInverseTable = "admin_login_histories" // LoginHistoriesColumn is the table column denoting the login_histories relation/edge. - LoginHistoriesColumn = "admin_login_histories" + LoginHistoriesColumn = "admin_id" ) // Columns holds all SQL columns for admin fields. diff --git a/backend/db/admin_query.go b/backend/db/admin_query.go index b41db58..7e3558c 100644 --- a/backend/db/admin_query.go +++ b/backend/db/admin_query.go @@ -420,7 +420,9 @@ func (aq *AdminQuery) loadLoginHistories(ctx context.Context, query *AdminLoginH init(nodes[i]) } } - query.withFKs = true + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(adminloginhistory.FieldAdminID) + } query.Where(predicate.AdminLoginHistory(func(s *sql.Selector) { s.Where(sql.InValues(s.C(admin.LoginHistoriesColumn), fks...)) })) @@ -429,13 +431,10 @@ func (aq *AdminQuery) loadLoginHistories(ctx context.Context, query *AdminLoginH return err } for _, n := range neighbors { - fk := n.admin_login_histories - if fk == nil { - return fmt.Errorf(`foreign-key "admin_login_histories" is nil for node %v`, n.ID) - } - node, ok := nodeids[*fk] + fk := n.AdminID + node, ok := nodeids[fk] if !ok { - return fmt.Errorf(`unexpected referenced foreign-key "admin_login_histories" returned %v for node %v`, *fk, n.ID) + return fmt.Errorf(`unexpected referenced foreign-key "admin_id" returned %v for node %v`, fk, n.ID) } assign(node, n) } diff --git a/backend/db/adminloginhistory.go b/backend/db/adminloginhistory.go index 283b4b0..4d9284f 100644 --- a/backend/db/adminloginhistory.go +++ b/backend/db/adminloginhistory.go @@ -41,9 +41,8 @@ type AdminLoginHistory struct { CreatedAt time.Time `json:"created_at,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the AdminLoginHistoryQuery when eager-loading is set. - Edges AdminLoginHistoryEdges `json:"edges"` - admin_login_histories *uuid.UUID - selectValues sql.SelectValues + Edges AdminLoginHistoryEdges `json:"edges"` + selectValues sql.SelectValues } // AdminLoginHistoryEdges holds the relations/edges for other nodes in the graph. @@ -77,8 +76,6 @@ func (*AdminLoginHistory) scanValues(columns []string) ([]any, error) { values[i] = new(sql.NullTime) case adminloginhistory.FieldID, adminloginhistory.FieldAdminID: values[i] = new(uuid.UUID) - case adminloginhistory.ForeignKeys[0]: // admin_login_histories - values[i] = &sql.NullScanner{S: new(uuid.UUID)} default: values[i] = new(sql.UnknownType) } @@ -160,13 +157,6 @@ func (alh *AdminLoginHistory) assignValues(columns []string, values []any) error } else if value.Valid { alh.CreatedAt = value.Time } - case adminloginhistory.ForeignKeys[0]: - if value, ok := values[i].(*sql.NullScanner); !ok { - return fmt.Errorf("unexpected type %T for field admin_login_histories", values[i]) - } else if value.Valid { - alh.admin_login_histories = new(uuid.UUID) - *alh.admin_login_histories = *value.S.(*uuid.UUID) - } default: alh.selectValues.Set(columns[i], values[i]) } diff --git a/backend/db/adminloginhistory/adminloginhistory.go b/backend/db/adminloginhistory/adminloginhistory.go index 720b07a..1cb70ce 100644 --- a/backend/db/adminloginhistory/adminloginhistory.go +++ b/backend/db/adminloginhistory/adminloginhistory.go @@ -44,7 +44,7 @@ const ( // It exists in this package in order to avoid circular dependency with the "admin" package. OwnerInverseTable = "admins" // OwnerColumn is the table column denoting the owner relation/edge. - OwnerColumn = "admin_login_histories" + OwnerColumn = "admin_id" ) // Columns holds all SQL columns for adminloginhistory fields. @@ -62,12 +62,6 @@ var Columns = []string{ FieldCreatedAt, } -// ForeignKeys holds the SQL foreign-keys that are owned by the "admin_login_histories" -// table and are not defined as standalone fields in the schema. -var ForeignKeys = []string{ - "admin_login_histories", -} - // ValidColumn reports if the column name is valid (part of the table columns). func ValidColumn(column string) bool { for i := range Columns { @@ -75,11 +69,6 @@ func ValidColumn(column string) bool { return true } } - for i := range ForeignKeys { - if column == ForeignKeys[i] { - return true - } - } return false } diff --git a/backend/db/adminloginhistory/where.go b/backend/db/adminloginhistory/where.go index 910ad33..db11463 100644 --- a/backend/db/adminloginhistory/where.go +++ b/backend/db/adminloginhistory/where.go @@ -126,24 +126,14 @@ func AdminIDNotIn(vs ...uuid.UUID) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldNotIn(FieldAdminID, vs...)) } -// AdminIDGT applies the GT predicate on the "admin_id" field. -func AdminIDGT(v uuid.UUID) predicate.AdminLoginHistory { - return predicate.AdminLoginHistory(sql.FieldGT(FieldAdminID, v)) +// AdminIDIsNil applies the IsNil predicate on the "admin_id" field. +func AdminIDIsNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldIsNull(FieldAdminID)) } -// AdminIDGTE applies the GTE predicate on the "admin_id" field. -func AdminIDGTE(v uuid.UUID) predicate.AdminLoginHistory { - return predicate.AdminLoginHistory(sql.FieldGTE(FieldAdminID, v)) -} - -// AdminIDLT applies the LT predicate on the "admin_id" field. -func AdminIDLT(v uuid.UUID) predicate.AdminLoginHistory { - return predicate.AdminLoginHistory(sql.FieldLT(FieldAdminID, v)) -} - -// AdminIDLTE applies the LTE predicate on the "admin_id" field. -func AdminIDLTE(v uuid.UUID) predicate.AdminLoginHistory { - return predicate.AdminLoginHistory(sql.FieldLTE(FieldAdminID, v)) +// AdminIDNotNil applies the NotNil predicate on the "admin_id" field. +func AdminIDNotNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldNotNull(FieldAdminID)) } // IPEQ applies the EQ predicate on the "ip" field. @@ -461,6 +451,16 @@ func IspHasSuffix(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldHasSuffix(FieldIsp, v)) } +// IspIsNil applies the IsNil predicate on the "isp" field. +func IspIsNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldIsNull(FieldIsp)) +} + +// IspNotNil applies the NotNil predicate on the "isp" field. +func IspNotNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldNotNull(FieldIsp)) +} + // IspEqualFold applies the EqualFold predicate on the "isp" field. func IspEqualFold(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldEqualFold(FieldIsp, v)) @@ -526,6 +526,16 @@ func AsnHasSuffix(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldHasSuffix(FieldAsn, v)) } +// AsnIsNil applies the IsNil predicate on the "asn" field. +func AsnIsNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldIsNull(FieldAsn)) +} + +// AsnNotNil applies the NotNil predicate on the "asn" field. +func AsnNotNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldNotNull(FieldAsn)) +} + // AsnEqualFold applies the EqualFold predicate on the "asn" field. func AsnEqualFold(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldEqualFold(FieldAsn, v)) @@ -591,6 +601,16 @@ func ClientVersionHasSuffix(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldHasSuffix(FieldClientVersion, v)) } +// ClientVersionIsNil applies the IsNil predicate on the "client_version" field. +func ClientVersionIsNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldIsNull(FieldClientVersion)) +} + +// ClientVersionNotNil applies the NotNil predicate on the "client_version" field. +func ClientVersionNotNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldNotNull(FieldClientVersion)) +} + // ClientVersionEqualFold applies the EqualFold predicate on the "client_version" field. func ClientVersionEqualFold(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldEqualFold(FieldClientVersion, v)) @@ -656,6 +676,16 @@ func DeviceHasSuffix(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldHasSuffix(FieldDevice, v)) } +// DeviceIsNil applies the IsNil predicate on the "device" field. +func DeviceIsNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldIsNull(FieldDevice)) +} + +// DeviceNotNil applies the NotNil predicate on the "device" field. +func DeviceNotNil() predicate.AdminLoginHistory { + return predicate.AdminLoginHistory(sql.FieldNotNull(FieldDevice)) +} + // DeviceEqualFold applies the EqualFold predicate on the "device" field. func DeviceEqualFold(v string) predicate.AdminLoginHistory { return predicate.AdminLoginHistory(sql.FieldEqualFold(FieldDevice, v)) diff --git a/backend/db/adminloginhistory_create.go b/backend/db/adminloginhistory_create.go index dfef7fa..279f616 100644 --- a/backend/db/adminloginhistory_create.go +++ b/backend/db/adminloginhistory_create.go @@ -31,6 +31,14 @@ func (alhc *AdminLoginHistoryCreate) SetAdminID(u uuid.UUID) *AdminLoginHistoryC return alhc } +// SetNillableAdminID sets the "admin_id" field if the given value is not nil. +func (alhc *AdminLoginHistoryCreate) SetNillableAdminID(u *uuid.UUID) *AdminLoginHistoryCreate { + if u != nil { + alhc.SetAdminID(*u) + } + return alhc +} + // SetIP sets the "ip" field. func (alhc *AdminLoginHistoryCreate) SetIP(s string) *AdminLoginHistoryCreate { alhc.mutation.SetIP(s) @@ -61,24 +69,56 @@ func (alhc *AdminLoginHistoryCreate) SetIsp(s string) *AdminLoginHistoryCreate { return alhc } +// SetNillableIsp sets the "isp" field if the given value is not nil. +func (alhc *AdminLoginHistoryCreate) SetNillableIsp(s *string) *AdminLoginHistoryCreate { + if s != nil { + alhc.SetIsp(*s) + } + return alhc +} + // SetAsn sets the "asn" field. func (alhc *AdminLoginHistoryCreate) SetAsn(s string) *AdminLoginHistoryCreate { alhc.mutation.SetAsn(s) return alhc } +// SetNillableAsn sets the "asn" field if the given value is not nil. +func (alhc *AdminLoginHistoryCreate) SetNillableAsn(s *string) *AdminLoginHistoryCreate { + if s != nil { + alhc.SetAsn(*s) + } + return alhc +} + // SetClientVersion sets the "client_version" field. func (alhc *AdminLoginHistoryCreate) SetClientVersion(s string) *AdminLoginHistoryCreate { alhc.mutation.SetClientVersion(s) return alhc } +// SetNillableClientVersion sets the "client_version" field if the given value is not nil. +func (alhc *AdminLoginHistoryCreate) SetNillableClientVersion(s *string) *AdminLoginHistoryCreate { + if s != nil { + alhc.SetClientVersion(*s) + } + return alhc +} + // SetDevice sets the "device" field. func (alhc *AdminLoginHistoryCreate) SetDevice(s string) *AdminLoginHistoryCreate { alhc.mutation.SetDevice(s) return alhc } +// SetNillableDevice sets the "device" field if the given value is not nil. +func (alhc *AdminLoginHistoryCreate) SetNillableDevice(s *string) *AdminLoginHistoryCreate { + if s != nil { + alhc.SetDevice(*s) + } + return alhc +} + // SetCreatedAt sets the "created_at" field. func (alhc *AdminLoginHistoryCreate) SetCreatedAt(t time.Time) *AdminLoginHistoryCreate { alhc.mutation.SetCreatedAt(t) @@ -161,9 +201,6 @@ func (alhc *AdminLoginHistoryCreate) defaults() { // check runs all checks and user-defined validators on the builder. func (alhc *AdminLoginHistoryCreate) check() error { - if _, ok := alhc.mutation.AdminID(); !ok { - return &ValidationError{Name: "admin_id", err: errors.New(`db: missing required field "AdminLoginHistory.admin_id"`)} - } if _, ok := alhc.mutation.IP(); !ok { return &ValidationError{Name: "ip", err: errors.New(`db: missing required field "AdminLoginHistory.ip"`)} } @@ -176,18 +213,6 @@ func (alhc *AdminLoginHistoryCreate) check() error { if _, ok := alhc.mutation.City(); !ok { return &ValidationError{Name: "city", err: errors.New(`db: missing required field "AdminLoginHistory.city"`)} } - if _, ok := alhc.mutation.Isp(); !ok { - return &ValidationError{Name: "isp", err: errors.New(`db: missing required field "AdminLoginHistory.isp"`)} - } - if _, ok := alhc.mutation.Asn(); !ok { - return &ValidationError{Name: "asn", err: errors.New(`db: missing required field "AdminLoginHistory.asn"`)} - } - if _, ok := alhc.mutation.ClientVersion(); !ok { - return &ValidationError{Name: "client_version", err: errors.New(`db: missing required field "AdminLoginHistory.client_version"`)} - } - if _, ok := alhc.mutation.Device(); !ok { - return &ValidationError{Name: "device", err: errors.New(`db: missing required field "AdminLoginHistory.device"`)} - } if _, ok := alhc.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`db: missing required field "AdminLoginHistory.created_at"`)} } @@ -227,10 +252,6 @@ func (alhc *AdminLoginHistoryCreate) createSpec() (*AdminLoginHistory, *sqlgraph _node.ID = id _spec.ID.Value = &id } - if value, ok := alhc.mutation.AdminID(); ok { - _spec.SetField(adminloginhistory.FieldAdminID, field.TypeUUID, value) - _node.AdminID = value - } if value, ok := alhc.mutation.IP(); ok { _spec.SetField(adminloginhistory.FieldIP, field.TypeString, value) _node.IP = value @@ -281,7 +302,7 @@ func (alhc *AdminLoginHistoryCreate) createSpec() (*AdminLoginHistory, *sqlgraph for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } - _node.admin_login_histories = &nodes[0] + _node.AdminID = nodes[0] _spec.Edges = append(_spec.Edges, edge) } return _node, _spec @@ -348,6 +369,12 @@ func (u *AdminLoginHistoryUpsert) UpdateAdminID() *AdminLoginHistoryUpsert { return u } +// ClearAdminID clears the value of the "admin_id" field. +func (u *AdminLoginHistoryUpsert) ClearAdminID() *AdminLoginHistoryUpsert { + u.SetNull(adminloginhistory.FieldAdminID) + return u +} + // SetIP sets the "ip" field. func (u *AdminLoginHistoryUpsert) SetIP(v string) *AdminLoginHistoryUpsert { u.Set(adminloginhistory.FieldIP, v) @@ -408,6 +435,12 @@ func (u *AdminLoginHistoryUpsert) UpdateIsp() *AdminLoginHistoryUpsert { return u } +// ClearIsp clears the value of the "isp" field. +func (u *AdminLoginHistoryUpsert) ClearIsp() *AdminLoginHistoryUpsert { + u.SetNull(adminloginhistory.FieldIsp) + return u +} + // SetAsn sets the "asn" field. func (u *AdminLoginHistoryUpsert) SetAsn(v string) *AdminLoginHistoryUpsert { u.Set(adminloginhistory.FieldAsn, v) @@ -420,6 +453,12 @@ func (u *AdminLoginHistoryUpsert) UpdateAsn() *AdminLoginHistoryUpsert { return u } +// ClearAsn clears the value of the "asn" field. +func (u *AdminLoginHistoryUpsert) ClearAsn() *AdminLoginHistoryUpsert { + u.SetNull(adminloginhistory.FieldAsn) + return u +} + // SetClientVersion sets the "client_version" field. func (u *AdminLoginHistoryUpsert) SetClientVersion(v string) *AdminLoginHistoryUpsert { u.Set(adminloginhistory.FieldClientVersion, v) @@ -432,6 +471,12 @@ func (u *AdminLoginHistoryUpsert) UpdateClientVersion() *AdminLoginHistoryUpsert return u } +// ClearClientVersion clears the value of the "client_version" field. +func (u *AdminLoginHistoryUpsert) ClearClientVersion() *AdminLoginHistoryUpsert { + u.SetNull(adminloginhistory.FieldClientVersion) + return u +} + // SetDevice sets the "device" field. func (u *AdminLoginHistoryUpsert) SetDevice(v string) *AdminLoginHistoryUpsert { u.Set(adminloginhistory.FieldDevice, v) @@ -444,6 +489,12 @@ func (u *AdminLoginHistoryUpsert) UpdateDevice() *AdminLoginHistoryUpsert { return u } +// ClearDevice clears the value of the "device" field. +func (u *AdminLoginHistoryUpsert) ClearDevice() *AdminLoginHistoryUpsert { + u.SetNull(adminloginhistory.FieldDevice) + return u +} + // SetCreatedAt sets the "created_at" field. func (u *AdminLoginHistoryUpsert) SetCreatedAt(v time.Time) *AdminLoginHistoryUpsert { u.Set(adminloginhistory.FieldCreatedAt, v) @@ -518,6 +569,13 @@ func (u *AdminLoginHistoryUpsertOne) UpdateAdminID() *AdminLoginHistoryUpsertOne }) } +// ClearAdminID clears the value of the "admin_id" field. +func (u *AdminLoginHistoryUpsertOne) ClearAdminID() *AdminLoginHistoryUpsertOne { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearAdminID() + }) +} + // SetIP sets the "ip" field. func (u *AdminLoginHistoryUpsertOne) SetIP(v string) *AdminLoginHistoryUpsertOne { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -588,6 +646,13 @@ func (u *AdminLoginHistoryUpsertOne) UpdateIsp() *AdminLoginHistoryUpsertOne { }) } +// ClearIsp clears the value of the "isp" field. +func (u *AdminLoginHistoryUpsertOne) ClearIsp() *AdminLoginHistoryUpsertOne { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearIsp() + }) +} + // SetAsn sets the "asn" field. func (u *AdminLoginHistoryUpsertOne) SetAsn(v string) *AdminLoginHistoryUpsertOne { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -602,6 +667,13 @@ func (u *AdminLoginHistoryUpsertOne) UpdateAsn() *AdminLoginHistoryUpsertOne { }) } +// ClearAsn clears the value of the "asn" field. +func (u *AdminLoginHistoryUpsertOne) ClearAsn() *AdminLoginHistoryUpsertOne { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearAsn() + }) +} + // SetClientVersion sets the "client_version" field. func (u *AdminLoginHistoryUpsertOne) SetClientVersion(v string) *AdminLoginHistoryUpsertOne { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -616,6 +688,13 @@ func (u *AdminLoginHistoryUpsertOne) UpdateClientVersion() *AdminLoginHistoryUps }) } +// ClearClientVersion clears the value of the "client_version" field. +func (u *AdminLoginHistoryUpsertOne) ClearClientVersion() *AdminLoginHistoryUpsertOne { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearClientVersion() + }) +} + // SetDevice sets the "device" field. func (u *AdminLoginHistoryUpsertOne) SetDevice(v string) *AdminLoginHistoryUpsertOne { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -630,6 +709,13 @@ func (u *AdminLoginHistoryUpsertOne) UpdateDevice() *AdminLoginHistoryUpsertOne }) } +// ClearDevice clears the value of the "device" field. +func (u *AdminLoginHistoryUpsertOne) ClearDevice() *AdminLoginHistoryUpsertOne { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearDevice() + }) +} + // SetCreatedAt sets the "created_at" field. func (u *AdminLoginHistoryUpsertOne) SetCreatedAt(v time.Time) *AdminLoginHistoryUpsertOne { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -873,6 +959,13 @@ func (u *AdminLoginHistoryUpsertBulk) UpdateAdminID() *AdminLoginHistoryUpsertBu }) } +// ClearAdminID clears the value of the "admin_id" field. +func (u *AdminLoginHistoryUpsertBulk) ClearAdminID() *AdminLoginHistoryUpsertBulk { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearAdminID() + }) +} + // SetIP sets the "ip" field. func (u *AdminLoginHistoryUpsertBulk) SetIP(v string) *AdminLoginHistoryUpsertBulk { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -943,6 +1036,13 @@ func (u *AdminLoginHistoryUpsertBulk) UpdateIsp() *AdminLoginHistoryUpsertBulk { }) } +// ClearIsp clears the value of the "isp" field. +func (u *AdminLoginHistoryUpsertBulk) ClearIsp() *AdminLoginHistoryUpsertBulk { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearIsp() + }) +} + // SetAsn sets the "asn" field. func (u *AdminLoginHistoryUpsertBulk) SetAsn(v string) *AdminLoginHistoryUpsertBulk { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -957,6 +1057,13 @@ func (u *AdminLoginHistoryUpsertBulk) UpdateAsn() *AdminLoginHistoryUpsertBulk { }) } +// ClearAsn clears the value of the "asn" field. +func (u *AdminLoginHistoryUpsertBulk) ClearAsn() *AdminLoginHistoryUpsertBulk { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearAsn() + }) +} + // SetClientVersion sets the "client_version" field. func (u *AdminLoginHistoryUpsertBulk) SetClientVersion(v string) *AdminLoginHistoryUpsertBulk { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -971,6 +1078,13 @@ func (u *AdminLoginHistoryUpsertBulk) UpdateClientVersion() *AdminLoginHistoryUp }) } +// ClearClientVersion clears the value of the "client_version" field. +func (u *AdminLoginHistoryUpsertBulk) ClearClientVersion() *AdminLoginHistoryUpsertBulk { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearClientVersion() + }) +} + // SetDevice sets the "device" field. func (u *AdminLoginHistoryUpsertBulk) SetDevice(v string) *AdminLoginHistoryUpsertBulk { return u.Update(func(s *AdminLoginHistoryUpsert) { @@ -985,6 +1099,13 @@ func (u *AdminLoginHistoryUpsertBulk) UpdateDevice() *AdminLoginHistoryUpsertBul }) } +// ClearDevice clears the value of the "device" field. +func (u *AdminLoginHistoryUpsertBulk) ClearDevice() *AdminLoginHistoryUpsertBulk { + return u.Update(func(s *AdminLoginHistoryUpsert) { + s.ClearDevice() + }) +} + // SetCreatedAt sets the "created_at" field. func (u *AdminLoginHistoryUpsertBulk) SetCreatedAt(v time.Time) *AdminLoginHistoryUpsertBulk { return u.Update(func(s *AdminLoginHistoryUpsert) { diff --git a/backend/db/adminloginhistory_query.go b/backend/db/adminloginhistory_query.go index afac175..a31d590 100644 --- a/backend/db/adminloginhistory_query.go +++ b/backend/db/adminloginhistory_query.go @@ -26,7 +26,6 @@ type AdminLoginHistoryQuery struct { inters []Interceptor predicates []predicate.AdminLoginHistory withOwner *AdminQuery - withFKs bool modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). sql *sql.Selector @@ -374,18 +373,11 @@ func (alhq *AdminLoginHistoryQuery) prepareQuery(ctx context.Context) error { func (alhq *AdminLoginHistoryQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AdminLoginHistory, error) { var ( nodes = []*AdminLoginHistory{} - withFKs = alhq.withFKs _spec = alhq.querySpec() loadedTypes = [1]bool{ alhq.withOwner != nil, } ) - if alhq.withOwner != nil { - withFKs = true - } - if withFKs { - _spec.Node.Columns = append(_spec.Node.Columns, adminloginhistory.ForeignKeys...) - } _spec.ScanValues = func(columns []string) ([]any, error) { return (*AdminLoginHistory).scanValues(nil, columns) } @@ -420,10 +412,7 @@ func (alhq *AdminLoginHistoryQuery) loadOwner(ctx context.Context, query *AdminQ ids := make([]uuid.UUID, 0, len(nodes)) nodeids := make(map[uuid.UUID][]*AdminLoginHistory) for i := range nodes { - if nodes[i].admin_login_histories == nil { - continue - } - fk := *nodes[i].admin_login_histories + fk := nodes[i].AdminID if _, ok := nodeids[fk]; !ok { ids = append(ids, fk) } @@ -440,7 +429,7 @@ func (alhq *AdminLoginHistoryQuery) loadOwner(ctx context.Context, query *AdminQ for _, n := range neighbors { nodes, ok := nodeids[n.ID] if !ok { - return fmt.Errorf(`unexpected foreign-key "admin_login_histories" returned %v`, n.ID) + return fmt.Errorf(`unexpected foreign-key "admin_id" returned %v`, n.ID) } for i := range nodes { assign(nodes[i], n) @@ -477,6 +466,9 @@ func (alhq *AdminLoginHistoryQuery) querySpec() *sqlgraph.QuerySpec { _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) } } + if alhq.withOwner != nil { + _spec.Node.AddColumnOnce(adminloginhistory.FieldAdminID) + } } if ps := alhq.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { diff --git a/backend/db/adminloginhistory_update.go b/backend/db/adminloginhistory_update.go index 3f58dae..063dde5 100644 --- a/backend/db/adminloginhistory_update.go +++ b/backend/db/adminloginhistory_update.go @@ -45,6 +45,12 @@ func (alhu *AdminLoginHistoryUpdate) SetNillableAdminID(u *uuid.UUID) *AdminLogi return alhu } +// ClearAdminID clears the value of the "admin_id" field. +func (alhu *AdminLoginHistoryUpdate) ClearAdminID() *AdminLoginHistoryUpdate { + alhu.mutation.ClearAdminID() + return alhu +} + // SetIP sets the "ip" field. func (alhu *AdminLoginHistoryUpdate) SetIP(s string) *AdminLoginHistoryUpdate { alhu.mutation.SetIP(s) @@ -115,6 +121,12 @@ func (alhu *AdminLoginHistoryUpdate) SetNillableIsp(s *string) *AdminLoginHistor return alhu } +// ClearIsp clears the value of the "isp" field. +func (alhu *AdminLoginHistoryUpdate) ClearIsp() *AdminLoginHistoryUpdate { + alhu.mutation.ClearIsp() + return alhu +} + // SetAsn sets the "asn" field. func (alhu *AdminLoginHistoryUpdate) SetAsn(s string) *AdminLoginHistoryUpdate { alhu.mutation.SetAsn(s) @@ -129,6 +141,12 @@ func (alhu *AdminLoginHistoryUpdate) SetNillableAsn(s *string) *AdminLoginHistor return alhu } +// ClearAsn clears the value of the "asn" field. +func (alhu *AdminLoginHistoryUpdate) ClearAsn() *AdminLoginHistoryUpdate { + alhu.mutation.ClearAsn() + return alhu +} + // SetClientVersion sets the "client_version" field. func (alhu *AdminLoginHistoryUpdate) SetClientVersion(s string) *AdminLoginHistoryUpdate { alhu.mutation.SetClientVersion(s) @@ -143,6 +161,12 @@ func (alhu *AdminLoginHistoryUpdate) SetNillableClientVersion(s *string) *AdminL return alhu } +// ClearClientVersion clears the value of the "client_version" field. +func (alhu *AdminLoginHistoryUpdate) ClearClientVersion() *AdminLoginHistoryUpdate { + alhu.mutation.ClearClientVersion() + return alhu +} + // SetDevice sets the "device" field. func (alhu *AdminLoginHistoryUpdate) SetDevice(s string) *AdminLoginHistoryUpdate { alhu.mutation.SetDevice(s) @@ -157,6 +181,12 @@ func (alhu *AdminLoginHistoryUpdate) SetNillableDevice(s *string) *AdminLoginHis return alhu } +// ClearDevice clears the value of the "device" field. +func (alhu *AdminLoginHistoryUpdate) ClearDevice() *AdminLoginHistoryUpdate { + alhu.mutation.ClearDevice() + return alhu +} + // SetCreatedAt sets the "created_at" field. func (alhu *AdminLoginHistoryUpdate) SetCreatedAt(t time.Time) *AdminLoginHistoryUpdate { alhu.mutation.SetCreatedAt(t) @@ -243,9 +273,6 @@ func (alhu *AdminLoginHistoryUpdate) sqlSave(ctx context.Context) (n int, err er } } } - if value, ok := alhu.mutation.AdminID(); ok { - _spec.SetField(adminloginhistory.FieldAdminID, field.TypeUUID, value) - } if value, ok := alhu.mutation.IP(); ok { _spec.SetField(adminloginhistory.FieldIP, field.TypeString, value) } @@ -261,15 +288,27 @@ func (alhu *AdminLoginHistoryUpdate) sqlSave(ctx context.Context) (n int, err er if value, ok := alhu.mutation.Isp(); ok { _spec.SetField(adminloginhistory.FieldIsp, field.TypeString, value) } + if alhu.mutation.IspCleared() { + _spec.ClearField(adminloginhistory.FieldIsp, field.TypeString) + } if value, ok := alhu.mutation.Asn(); ok { _spec.SetField(adminloginhistory.FieldAsn, field.TypeString, value) } + if alhu.mutation.AsnCleared() { + _spec.ClearField(adminloginhistory.FieldAsn, field.TypeString) + } if value, ok := alhu.mutation.ClientVersion(); ok { _spec.SetField(adminloginhistory.FieldClientVersion, field.TypeString, value) } + if alhu.mutation.ClientVersionCleared() { + _spec.ClearField(adminloginhistory.FieldClientVersion, field.TypeString) + } if value, ok := alhu.mutation.Device(); ok { _spec.SetField(adminloginhistory.FieldDevice, field.TypeString, value) } + if alhu.mutation.DeviceCleared() { + _spec.ClearField(adminloginhistory.FieldDevice, field.TypeString) + } if value, ok := alhu.mutation.CreatedAt(); ok { _spec.SetField(adminloginhistory.FieldCreatedAt, field.TypeTime, value) } @@ -338,6 +377,12 @@ func (alhuo *AdminLoginHistoryUpdateOne) SetNillableAdminID(u *uuid.UUID) *Admin return alhuo } +// ClearAdminID clears the value of the "admin_id" field. +func (alhuo *AdminLoginHistoryUpdateOne) ClearAdminID() *AdminLoginHistoryUpdateOne { + alhuo.mutation.ClearAdminID() + return alhuo +} + // SetIP sets the "ip" field. func (alhuo *AdminLoginHistoryUpdateOne) SetIP(s string) *AdminLoginHistoryUpdateOne { alhuo.mutation.SetIP(s) @@ -408,6 +453,12 @@ func (alhuo *AdminLoginHistoryUpdateOne) SetNillableIsp(s *string) *AdminLoginHi return alhuo } +// ClearIsp clears the value of the "isp" field. +func (alhuo *AdminLoginHistoryUpdateOne) ClearIsp() *AdminLoginHistoryUpdateOne { + alhuo.mutation.ClearIsp() + return alhuo +} + // SetAsn sets the "asn" field. func (alhuo *AdminLoginHistoryUpdateOne) SetAsn(s string) *AdminLoginHistoryUpdateOne { alhuo.mutation.SetAsn(s) @@ -422,6 +473,12 @@ func (alhuo *AdminLoginHistoryUpdateOne) SetNillableAsn(s *string) *AdminLoginHi return alhuo } +// ClearAsn clears the value of the "asn" field. +func (alhuo *AdminLoginHistoryUpdateOne) ClearAsn() *AdminLoginHistoryUpdateOne { + alhuo.mutation.ClearAsn() + return alhuo +} + // SetClientVersion sets the "client_version" field. func (alhuo *AdminLoginHistoryUpdateOne) SetClientVersion(s string) *AdminLoginHistoryUpdateOne { alhuo.mutation.SetClientVersion(s) @@ -436,6 +493,12 @@ func (alhuo *AdminLoginHistoryUpdateOne) SetNillableClientVersion(s *string) *Ad return alhuo } +// ClearClientVersion clears the value of the "client_version" field. +func (alhuo *AdminLoginHistoryUpdateOne) ClearClientVersion() *AdminLoginHistoryUpdateOne { + alhuo.mutation.ClearClientVersion() + return alhuo +} + // SetDevice sets the "device" field. func (alhuo *AdminLoginHistoryUpdateOne) SetDevice(s string) *AdminLoginHistoryUpdateOne { alhuo.mutation.SetDevice(s) @@ -450,6 +513,12 @@ func (alhuo *AdminLoginHistoryUpdateOne) SetNillableDevice(s *string) *AdminLogi return alhuo } +// ClearDevice clears the value of the "device" field. +func (alhuo *AdminLoginHistoryUpdateOne) ClearDevice() *AdminLoginHistoryUpdateOne { + alhuo.mutation.ClearDevice() + return alhuo +} + // SetCreatedAt sets the "created_at" field. func (alhuo *AdminLoginHistoryUpdateOne) SetCreatedAt(t time.Time) *AdminLoginHistoryUpdateOne { alhuo.mutation.SetCreatedAt(t) @@ -566,9 +635,6 @@ func (alhuo *AdminLoginHistoryUpdateOne) sqlSave(ctx context.Context) (_node *Ad } } } - if value, ok := alhuo.mutation.AdminID(); ok { - _spec.SetField(adminloginhistory.FieldAdminID, field.TypeUUID, value) - } if value, ok := alhuo.mutation.IP(); ok { _spec.SetField(adminloginhistory.FieldIP, field.TypeString, value) } @@ -584,15 +650,27 @@ func (alhuo *AdminLoginHistoryUpdateOne) sqlSave(ctx context.Context) (_node *Ad if value, ok := alhuo.mutation.Isp(); ok { _spec.SetField(adminloginhistory.FieldIsp, field.TypeString, value) } + if alhuo.mutation.IspCleared() { + _spec.ClearField(adminloginhistory.FieldIsp, field.TypeString) + } if value, ok := alhuo.mutation.Asn(); ok { _spec.SetField(adminloginhistory.FieldAsn, field.TypeString, value) } + if alhuo.mutation.AsnCleared() { + _spec.ClearField(adminloginhistory.FieldAsn, field.TypeString) + } if value, ok := alhuo.mutation.ClientVersion(); ok { _spec.SetField(adminloginhistory.FieldClientVersion, field.TypeString, value) } + if alhuo.mutation.ClientVersionCleared() { + _spec.ClearField(adminloginhistory.FieldClientVersion, field.TypeString) + } if value, ok := alhuo.mutation.Device(); ok { _spec.SetField(adminloginhistory.FieldDevice, field.TypeString, value) } + if alhuo.mutation.DeviceCleared() { + _spec.ClearField(adminloginhistory.FieldDevice, field.TypeString) + } if value, ok := alhuo.mutation.CreatedAt(); ok { _spec.SetField(adminloginhistory.FieldCreatedAt, field.TypeTime, value) } diff --git a/backend/db/migrate/schema.go b/backend/db/migrate/schema.go index eb99124..82ddcfa 100644 --- a/backend/db/migrate/schema.go +++ b/backend/db/migrate/schema.go @@ -28,17 +28,16 @@ var ( // AdminLoginHistoriesColumns holds the columns for the "admin_login_histories" table. AdminLoginHistoriesColumns = []*schema.Column{ {Name: "id", Type: field.TypeUUID}, - {Name: "admin_id", Type: field.TypeUUID}, {Name: "ip", Type: field.TypeString}, {Name: "country", Type: field.TypeString}, {Name: "province", Type: field.TypeString}, {Name: "city", Type: field.TypeString}, - {Name: "isp", Type: field.TypeString}, - {Name: "asn", Type: field.TypeString}, - {Name: "client_version", Type: field.TypeString}, - {Name: "device", Type: field.TypeString}, + {Name: "isp", Type: field.TypeString, Nullable: true}, + {Name: "asn", Type: field.TypeString, Nullable: true}, + {Name: "client_version", Type: field.TypeString, Nullable: true}, + {Name: "device", Type: field.TypeString, Nullable: true}, {Name: "created_at", Type: field.TypeTime}, - {Name: "admin_login_histories", Type: field.TypeUUID, Nullable: true}, + {Name: "admin_id", Type: field.TypeUUID, Nullable: true}, } // AdminLoginHistoriesTable holds the schema information for the "admin_login_histories" table. AdminLoginHistoriesTable = &schema.Table{ @@ -48,7 +47,7 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "admin_login_histories_admins_login_histories", - Columns: []*schema.Column{AdminLoginHistoriesColumns[11]}, + Columns: []*schema.Column{AdminLoginHistoriesColumns[10]}, RefColumns: []*schema.Column{AdminsColumns[0]}, OnDelete: schema.SetNull, }, @@ -370,17 +369,18 @@ var ( // UserLoginHistoriesColumns holds the columns for the "user_login_histories" table. UserLoginHistoriesColumns = []*schema.Column{ {Name: "id", Type: field.TypeUUID}, - {Name: "user_id", Type: field.TypeUUID}, {Name: "ip", Type: field.TypeString}, {Name: "country", Type: field.TypeString}, {Name: "province", Type: field.TypeString}, {Name: "city", Type: field.TypeString}, - {Name: "isp", Type: field.TypeString}, - {Name: "asn", Type: field.TypeString}, - {Name: "client_version", Type: field.TypeString}, - {Name: "device", Type: field.TypeString}, + {Name: "isp", Type: field.TypeString, Nullable: true}, + {Name: "asn", Type: field.TypeString, Nullable: true}, + {Name: "client_version", Type: field.TypeString, Nullable: true}, + {Name: "os_type", Type: field.TypeString, Nullable: true}, + {Name: "os_release", Type: field.TypeString, Nullable: true}, + {Name: "hostname", Type: field.TypeString, Nullable: true}, {Name: "created_at", Type: field.TypeTime}, - {Name: "user_login_histories", Type: field.TypeUUID, Nullable: true}, + {Name: "user_id", Type: field.TypeUUID, Nullable: true}, } // UserLoginHistoriesTable holds the schema information for the "user_login_histories" table. UserLoginHistoriesTable = &schema.Table{ @@ -390,7 +390,7 @@ var ( ForeignKeys: []*schema.ForeignKey{ { Symbol: "user_login_histories_users_login_histories", - Columns: []*schema.Column{UserLoginHistoriesColumns[11]}, + Columns: []*schema.Column{UserLoginHistoriesColumns[12]}, RefColumns: []*schema.Column{UsersColumns[0]}, OnDelete: schema.SetNull, }, diff --git a/backend/db/mutation.go b/backend/db/mutation.go index b8ca18f..7b711e1 100644 --- a/backend/db/mutation.go +++ b/backend/db/mutation.go @@ -765,7 +765,6 @@ type AdminLoginHistoryMutation struct { op Op typ string id *uuid.UUID - admin_id *uuid.UUID ip *string country *string province *string @@ -889,12 +888,12 @@ func (m *AdminLoginHistoryMutation) IDs(ctx context.Context) ([]uuid.UUID, error // SetAdminID sets the "admin_id" field. func (m *AdminLoginHistoryMutation) SetAdminID(u uuid.UUID) { - m.admin_id = &u + m.owner = &u } // AdminID returns the value of the "admin_id" field in the mutation. func (m *AdminLoginHistoryMutation) AdminID() (r uuid.UUID, exists bool) { - v := m.admin_id + v := m.owner if v == nil { return } @@ -918,9 +917,22 @@ func (m *AdminLoginHistoryMutation) OldAdminID(ctx context.Context) (v uuid.UUID return oldValue.AdminID, nil } +// ClearAdminID clears the value of the "admin_id" field. +func (m *AdminLoginHistoryMutation) ClearAdminID() { + m.owner = nil + m.clearedFields[adminloginhistory.FieldAdminID] = struct{}{} +} + +// AdminIDCleared returns if the "admin_id" field was cleared in this mutation. +func (m *AdminLoginHistoryMutation) AdminIDCleared() bool { + _, ok := m.clearedFields[adminloginhistory.FieldAdminID] + return ok +} + // ResetAdminID resets all changes to the "admin_id" field. func (m *AdminLoginHistoryMutation) ResetAdminID() { - m.admin_id = nil + m.owner = nil + delete(m.clearedFields, adminloginhistory.FieldAdminID) } // SetIP sets the "ip" field. @@ -1098,9 +1110,22 @@ func (m *AdminLoginHistoryMutation) OldIsp(ctx context.Context) (v string, err e return oldValue.Isp, nil } +// ClearIsp clears the value of the "isp" field. +func (m *AdminLoginHistoryMutation) ClearIsp() { + m.isp = nil + m.clearedFields[adminloginhistory.FieldIsp] = struct{}{} +} + +// IspCleared returns if the "isp" field was cleared in this mutation. +func (m *AdminLoginHistoryMutation) IspCleared() bool { + _, ok := m.clearedFields[adminloginhistory.FieldIsp] + return ok +} + // ResetIsp resets all changes to the "isp" field. func (m *AdminLoginHistoryMutation) ResetIsp() { m.isp = nil + delete(m.clearedFields, adminloginhistory.FieldIsp) } // SetAsn sets the "asn" field. @@ -1134,9 +1159,22 @@ func (m *AdminLoginHistoryMutation) OldAsn(ctx context.Context) (v string, err e return oldValue.Asn, nil } +// ClearAsn clears the value of the "asn" field. +func (m *AdminLoginHistoryMutation) ClearAsn() { + m.asn = nil + m.clearedFields[adminloginhistory.FieldAsn] = struct{}{} +} + +// AsnCleared returns if the "asn" field was cleared in this mutation. +func (m *AdminLoginHistoryMutation) AsnCleared() bool { + _, ok := m.clearedFields[adminloginhistory.FieldAsn] + return ok +} + // ResetAsn resets all changes to the "asn" field. func (m *AdminLoginHistoryMutation) ResetAsn() { m.asn = nil + delete(m.clearedFields, adminloginhistory.FieldAsn) } // SetClientVersion sets the "client_version" field. @@ -1170,9 +1208,22 @@ func (m *AdminLoginHistoryMutation) OldClientVersion(ctx context.Context) (v str return oldValue.ClientVersion, nil } +// ClearClientVersion clears the value of the "client_version" field. +func (m *AdminLoginHistoryMutation) ClearClientVersion() { + m.client_version = nil + m.clearedFields[adminloginhistory.FieldClientVersion] = struct{}{} +} + +// ClientVersionCleared returns if the "client_version" field was cleared in this mutation. +func (m *AdminLoginHistoryMutation) ClientVersionCleared() bool { + _, ok := m.clearedFields[adminloginhistory.FieldClientVersion] + return ok +} + // ResetClientVersion resets all changes to the "client_version" field. func (m *AdminLoginHistoryMutation) ResetClientVersion() { m.client_version = nil + delete(m.clearedFields, adminloginhistory.FieldClientVersion) } // SetDevice sets the "device" field. @@ -1206,9 +1257,22 @@ func (m *AdminLoginHistoryMutation) OldDevice(ctx context.Context) (v string, er return oldValue.Device, nil } +// ClearDevice clears the value of the "device" field. +func (m *AdminLoginHistoryMutation) ClearDevice() { + m.device = nil + m.clearedFields[adminloginhistory.FieldDevice] = struct{}{} +} + +// DeviceCleared returns if the "device" field was cleared in this mutation. +func (m *AdminLoginHistoryMutation) DeviceCleared() bool { + _, ok := m.clearedFields[adminloginhistory.FieldDevice] + return ok +} + // ResetDevice resets all changes to the "device" field. func (m *AdminLoginHistoryMutation) ResetDevice() { m.device = nil + delete(m.clearedFields, adminloginhistory.FieldDevice) } // SetCreatedAt sets the "created_at" field. @@ -1255,11 +1319,12 @@ func (m *AdminLoginHistoryMutation) SetOwnerID(id uuid.UUID) { // ClearOwner clears the "owner" edge to the Admin entity. func (m *AdminLoginHistoryMutation) ClearOwner() { m.clearedowner = true + m.clearedFields[adminloginhistory.FieldAdminID] = struct{}{} } // OwnerCleared reports if the "owner" edge to the Admin entity was cleared. func (m *AdminLoginHistoryMutation) OwnerCleared() bool { - return m.clearedowner + return m.AdminIDCleared() || m.clearedowner } // OwnerID returns the "owner" edge ID in the mutation. @@ -1321,7 +1386,7 @@ func (m *AdminLoginHistoryMutation) Type() string { // AddedFields(). func (m *AdminLoginHistoryMutation) Fields() []string { fields := make([]string, 0, 10) - if m.admin_id != nil { + if m.owner != nil { fields = append(fields, adminloginhistory.FieldAdminID) } if m.ip != nil { @@ -1516,7 +1581,23 @@ func (m *AdminLoginHistoryMutation) AddField(name string, value ent.Value) error // ClearedFields returns all nullable fields that were cleared during this // mutation. func (m *AdminLoginHistoryMutation) ClearedFields() []string { - return nil + var fields []string + if m.FieldCleared(adminloginhistory.FieldAdminID) { + fields = append(fields, adminloginhistory.FieldAdminID) + } + if m.FieldCleared(adminloginhistory.FieldIsp) { + fields = append(fields, adminloginhistory.FieldIsp) + } + if m.FieldCleared(adminloginhistory.FieldAsn) { + fields = append(fields, adminloginhistory.FieldAsn) + } + if m.FieldCleared(adminloginhistory.FieldClientVersion) { + fields = append(fields, adminloginhistory.FieldClientVersion) + } + if m.FieldCleared(adminloginhistory.FieldDevice) { + fields = append(fields, adminloginhistory.FieldDevice) + } + return fields } // FieldCleared returns a boolean indicating if a field with the given name was @@ -1529,6 +1610,23 @@ func (m *AdminLoginHistoryMutation) FieldCleared(name string) bool { // 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 *AdminLoginHistoryMutation) ClearField(name string) error { + switch name { + case adminloginhistory.FieldAdminID: + m.ClearAdminID() + return nil + case adminloginhistory.FieldIsp: + m.ClearIsp() + return nil + case adminloginhistory.FieldAsn: + m.ClearAsn() + return nil + case adminloginhistory.FieldClientVersion: + m.ClearClientVersion() + return nil + case adminloginhistory.FieldDevice: + m.ClearDevice() + return nil + } return fmt.Errorf("unknown AdminLoginHistory nullable field %s", name) } @@ -14189,7 +14287,6 @@ type UserLoginHistoryMutation struct { op Op typ string id *uuid.UUID - user_id *uuid.UUID ip *string country *string province *string @@ -14197,7 +14294,9 @@ type UserLoginHistoryMutation struct { isp *string asn *string client_version *string - device *string + os_type *consts.OSType + os_release *consts.OSRelease + hostname *string created_at *time.Time clearedFields map[string]struct{} owner *uuid.UUID @@ -14313,12 +14412,12 @@ func (m *UserLoginHistoryMutation) IDs(ctx context.Context) ([]uuid.UUID, error) // SetUserID sets the "user_id" field. func (m *UserLoginHistoryMutation) SetUserID(u uuid.UUID) { - m.user_id = &u + m.owner = &u } // UserID returns the value of the "user_id" field in the mutation. func (m *UserLoginHistoryMutation) UserID() (r uuid.UUID, exists bool) { - v := m.user_id + v := m.owner if v == nil { return } @@ -14342,9 +14441,22 @@ func (m *UserLoginHistoryMutation) OldUserID(ctx context.Context) (v uuid.UUID, return oldValue.UserID, nil } +// ClearUserID clears the value of the "user_id" field. +func (m *UserLoginHistoryMutation) ClearUserID() { + m.owner = nil + m.clearedFields[userloginhistory.FieldUserID] = struct{}{} +} + +// UserIDCleared returns if the "user_id" field was cleared in this mutation. +func (m *UserLoginHistoryMutation) UserIDCleared() bool { + _, ok := m.clearedFields[userloginhistory.FieldUserID] + return ok +} + // ResetUserID resets all changes to the "user_id" field. func (m *UserLoginHistoryMutation) ResetUserID() { - m.user_id = nil + m.owner = nil + delete(m.clearedFields, userloginhistory.FieldUserID) } // SetIP sets the "ip" field. @@ -14522,9 +14634,22 @@ func (m *UserLoginHistoryMutation) OldIsp(ctx context.Context) (v string, err er return oldValue.Isp, nil } +// ClearIsp clears the value of the "isp" field. +func (m *UserLoginHistoryMutation) ClearIsp() { + m.isp = nil + m.clearedFields[userloginhistory.FieldIsp] = struct{}{} +} + +// IspCleared returns if the "isp" field was cleared in this mutation. +func (m *UserLoginHistoryMutation) IspCleared() bool { + _, ok := m.clearedFields[userloginhistory.FieldIsp] + return ok +} + // ResetIsp resets all changes to the "isp" field. func (m *UserLoginHistoryMutation) ResetIsp() { m.isp = nil + delete(m.clearedFields, userloginhistory.FieldIsp) } // SetAsn sets the "asn" field. @@ -14558,9 +14683,22 @@ func (m *UserLoginHistoryMutation) OldAsn(ctx context.Context) (v string, err er return oldValue.Asn, nil } +// ClearAsn clears the value of the "asn" field. +func (m *UserLoginHistoryMutation) ClearAsn() { + m.asn = nil + m.clearedFields[userloginhistory.FieldAsn] = struct{}{} +} + +// AsnCleared returns if the "asn" field was cleared in this mutation. +func (m *UserLoginHistoryMutation) AsnCleared() bool { + _, ok := m.clearedFields[userloginhistory.FieldAsn] + return ok +} + // ResetAsn resets all changes to the "asn" field. func (m *UserLoginHistoryMutation) ResetAsn() { m.asn = nil + delete(m.clearedFields, userloginhistory.FieldAsn) } // SetClientVersion sets the "client_version" field. @@ -14594,45 +14732,169 @@ func (m *UserLoginHistoryMutation) OldClientVersion(ctx context.Context) (v stri return oldValue.ClientVersion, nil } +// ClearClientVersion clears the value of the "client_version" field. +func (m *UserLoginHistoryMutation) ClearClientVersion() { + m.client_version = nil + m.clearedFields[userloginhistory.FieldClientVersion] = struct{}{} +} + +// ClientVersionCleared returns if the "client_version" field was cleared in this mutation. +func (m *UserLoginHistoryMutation) ClientVersionCleared() bool { + _, ok := m.clearedFields[userloginhistory.FieldClientVersion] + return ok +} + // ResetClientVersion resets all changes to the "client_version" field. func (m *UserLoginHistoryMutation) ResetClientVersion() { m.client_version = nil + delete(m.clearedFields, userloginhistory.FieldClientVersion) } -// SetDevice sets the "device" field. -func (m *UserLoginHistoryMutation) SetDevice(s string) { - m.device = &s +// SetOsType sets the "os_type" field. +func (m *UserLoginHistoryMutation) SetOsType(ct consts.OSType) { + m.os_type = &ct } -// Device returns the value of the "device" field in the mutation. -func (m *UserLoginHistoryMutation) Device() (r string, exists bool) { - v := m.device +// OsType returns the value of the "os_type" field in the mutation. +func (m *UserLoginHistoryMutation) OsType() (r consts.OSType, exists bool) { + v := m.os_type if v == nil { return } return *v, true } -// OldDevice returns the old "device" field's value of the UserLoginHistory entity. +// OldOsType returns the old "os_type" field's value of the UserLoginHistory entity. // If the UserLoginHistory 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 *UserLoginHistoryMutation) OldDevice(ctx context.Context) (v string, err error) { +func (m *UserLoginHistoryMutation) OldOsType(ctx context.Context) (v consts.OSType, err error) { if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldDevice is only allowed on UpdateOne operations") + return v, errors.New("OldOsType is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { - return v, errors.New("OldDevice requires an ID field in the mutation") + return v, errors.New("OldOsType requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { - return v, fmt.Errorf("querying old value for OldDevice: %w", err) + return v, fmt.Errorf("querying old value for OldOsType: %w", err) } - return oldValue.Device, nil + return oldValue.OsType, nil } -// ResetDevice resets all changes to the "device" field. -func (m *UserLoginHistoryMutation) ResetDevice() { - m.device = nil +// ClearOsType clears the value of the "os_type" field. +func (m *UserLoginHistoryMutation) ClearOsType() { + m.os_type = nil + m.clearedFields[userloginhistory.FieldOsType] = struct{}{} +} + +// OsTypeCleared returns if the "os_type" field was cleared in this mutation. +func (m *UserLoginHistoryMutation) OsTypeCleared() bool { + _, ok := m.clearedFields[userloginhistory.FieldOsType] + return ok +} + +// ResetOsType resets all changes to the "os_type" field. +func (m *UserLoginHistoryMutation) ResetOsType() { + m.os_type = nil + delete(m.clearedFields, userloginhistory.FieldOsType) +} + +// SetOsRelease sets the "os_release" field. +func (m *UserLoginHistoryMutation) SetOsRelease(cr consts.OSRelease) { + m.os_release = &cr +} + +// OsRelease returns the value of the "os_release" field in the mutation. +func (m *UserLoginHistoryMutation) OsRelease() (r consts.OSRelease, exists bool) { + v := m.os_release + if v == nil { + return + } + return *v, true +} + +// OldOsRelease returns the old "os_release" field's value of the UserLoginHistory entity. +// If the UserLoginHistory 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 *UserLoginHistoryMutation) OldOsRelease(ctx context.Context) (v consts.OSRelease, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldOsRelease is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldOsRelease requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldOsRelease: %w", err) + } + return oldValue.OsRelease, nil +} + +// ClearOsRelease clears the value of the "os_release" field. +func (m *UserLoginHistoryMutation) ClearOsRelease() { + m.os_release = nil + m.clearedFields[userloginhistory.FieldOsRelease] = struct{}{} +} + +// OsReleaseCleared returns if the "os_release" field was cleared in this mutation. +func (m *UserLoginHistoryMutation) OsReleaseCleared() bool { + _, ok := m.clearedFields[userloginhistory.FieldOsRelease] + return ok +} + +// ResetOsRelease resets all changes to the "os_release" field. +func (m *UserLoginHistoryMutation) ResetOsRelease() { + m.os_release = nil + delete(m.clearedFields, userloginhistory.FieldOsRelease) +} + +// SetHostname sets the "hostname" field. +func (m *UserLoginHistoryMutation) SetHostname(s string) { + m.hostname = &s +} + +// Hostname returns the value of the "hostname" field in the mutation. +func (m *UserLoginHistoryMutation) Hostname() (r string, exists bool) { + v := m.hostname + if v == nil { + return + } + return *v, true +} + +// OldHostname returns the old "hostname" field's value of the UserLoginHistory entity. +// If the UserLoginHistory 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 *UserLoginHistoryMutation) OldHostname(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldHostname is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldHostname requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldHostname: %w", err) + } + return oldValue.Hostname, nil +} + +// ClearHostname clears the value of the "hostname" field. +func (m *UserLoginHistoryMutation) ClearHostname() { + m.hostname = nil + m.clearedFields[userloginhistory.FieldHostname] = struct{}{} +} + +// HostnameCleared returns if the "hostname" field was cleared in this mutation. +func (m *UserLoginHistoryMutation) HostnameCleared() bool { + _, ok := m.clearedFields[userloginhistory.FieldHostname] + return ok +} + +// ResetHostname resets all changes to the "hostname" field. +func (m *UserLoginHistoryMutation) ResetHostname() { + m.hostname = nil + delete(m.clearedFields, userloginhistory.FieldHostname) } // SetCreatedAt sets the "created_at" field. @@ -14679,11 +14941,12 @@ func (m *UserLoginHistoryMutation) SetOwnerID(id uuid.UUID) { // ClearOwner clears the "owner" edge to the User entity. func (m *UserLoginHistoryMutation) ClearOwner() { m.clearedowner = true + m.clearedFields[userloginhistory.FieldUserID] = struct{}{} } // OwnerCleared reports if the "owner" edge to the User entity was cleared. func (m *UserLoginHistoryMutation) OwnerCleared() bool { - return m.clearedowner + return m.UserIDCleared() || m.clearedowner } // OwnerID returns the "owner" edge ID in the mutation. @@ -14744,8 +15007,8 @@ func (m *UserLoginHistoryMutation) Type() string { // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *UserLoginHistoryMutation) Fields() []string { - fields := make([]string, 0, 10) - if m.user_id != nil { + fields := make([]string, 0, 12) + if m.owner != nil { fields = append(fields, userloginhistory.FieldUserID) } if m.ip != nil { @@ -14769,8 +15032,14 @@ func (m *UserLoginHistoryMutation) Fields() []string { if m.client_version != nil { fields = append(fields, userloginhistory.FieldClientVersion) } - if m.device != nil { - fields = append(fields, userloginhistory.FieldDevice) + if m.os_type != nil { + fields = append(fields, userloginhistory.FieldOsType) + } + if m.os_release != nil { + fields = append(fields, userloginhistory.FieldOsRelease) + } + if m.hostname != nil { + fields = append(fields, userloginhistory.FieldHostname) } if m.created_at != nil { fields = append(fields, userloginhistory.FieldCreatedAt) @@ -14799,8 +15068,12 @@ func (m *UserLoginHistoryMutation) Field(name string) (ent.Value, bool) { return m.Asn() case userloginhistory.FieldClientVersion: return m.ClientVersion() - case userloginhistory.FieldDevice: - return m.Device() + case userloginhistory.FieldOsType: + return m.OsType() + case userloginhistory.FieldOsRelease: + return m.OsRelease() + case userloginhistory.FieldHostname: + return m.Hostname() case userloginhistory.FieldCreatedAt: return m.CreatedAt() } @@ -14828,8 +15101,12 @@ func (m *UserLoginHistoryMutation) OldField(ctx context.Context, name string) (e return m.OldAsn(ctx) case userloginhistory.FieldClientVersion: return m.OldClientVersion(ctx) - case userloginhistory.FieldDevice: - return m.OldDevice(ctx) + case userloginhistory.FieldOsType: + return m.OldOsType(ctx) + case userloginhistory.FieldOsRelease: + return m.OldOsRelease(ctx) + case userloginhistory.FieldHostname: + return m.OldHostname(ctx) case userloginhistory.FieldCreatedAt: return m.OldCreatedAt(ctx) } @@ -14897,12 +15174,26 @@ func (m *UserLoginHistoryMutation) SetField(name string, value ent.Value) error } m.SetClientVersion(v) return nil - case userloginhistory.FieldDevice: + case userloginhistory.FieldOsType: + v, ok := value.(consts.OSType) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOsType(v) + return nil + case userloginhistory.FieldOsRelease: + v, ok := value.(consts.OSRelease) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetOsRelease(v) + return nil + case userloginhistory.FieldHostname: v, ok := value.(string) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } - m.SetDevice(v) + m.SetHostname(v) return nil case userloginhistory.FieldCreatedAt: v, ok := value.(time.Time) @@ -14940,7 +15231,29 @@ func (m *UserLoginHistoryMutation) AddField(name string, value ent.Value) error // ClearedFields returns all nullable fields that were cleared during this // mutation. func (m *UserLoginHistoryMutation) ClearedFields() []string { - return nil + var fields []string + if m.FieldCleared(userloginhistory.FieldUserID) { + fields = append(fields, userloginhistory.FieldUserID) + } + if m.FieldCleared(userloginhistory.FieldIsp) { + fields = append(fields, userloginhistory.FieldIsp) + } + if m.FieldCleared(userloginhistory.FieldAsn) { + fields = append(fields, userloginhistory.FieldAsn) + } + if m.FieldCleared(userloginhistory.FieldClientVersion) { + fields = append(fields, userloginhistory.FieldClientVersion) + } + if m.FieldCleared(userloginhistory.FieldOsType) { + fields = append(fields, userloginhistory.FieldOsType) + } + if m.FieldCleared(userloginhistory.FieldOsRelease) { + fields = append(fields, userloginhistory.FieldOsRelease) + } + if m.FieldCleared(userloginhistory.FieldHostname) { + fields = append(fields, userloginhistory.FieldHostname) + } + return fields } // FieldCleared returns a boolean indicating if a field with the given name was @@ -14953,6 +15266,29 @@ func (m *UserLoginHistoryMutation) FieldCleared(name string) bool { // 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 *UserLoginHistoryMutation) ClearField(name string) error { + switch name { + case userloginhistory.FieldUserID: + m.ClearUserID() + return nil + case userloginhistory.FieldIsp: + m.ClearIsp() + return nil + case userloginhistory.FieldAsn: + m.ClearAsn() + return nil + case userloginhistory.FieldClientVersion: + m.ClearClientVersion() + return nil + case userloginhistory.FieldOsType: + m.ClearOsType() + return nil + case userloginhistory.FieldOsRelease: + m.ClearOsRelease() + return nil + case userloginhistory.FieldHostname: + m.ClearHostname() + return nil + } return fmt.Errorf("unknown UserLoginHistory nullable field %s", name) } @@ -14984,8 +15320,14 @@ func (m *UserLoginHistoryMutation) ResetField(name string) error { case userloginhistory.FieldClientVersion: m.ResetClientVersion() return nil - case userloginhistory.FieldDevice: - m.ResetDevice() + case userloginhistory.FieldOsType: + m.ResetOsType() + return nil + case userloginhistory.FieldOsRelease: + m.ResetOsRelease() + return nil + case userloginhistory.FieldHostname: + m.ResetHostname() return nil case userloginhistory.FieldCreatedAt: m.ResetCreatedAt() diff --git a/backend/db/runtime/runtime.go b/backend/db/runtime/runtime.go index 9c62280..5110e1d 100644 --- a/backend/db/runtime/runtime.go +++ b/backend/db/runtime/runtime.go @@ -319,7 +319,7 @@ func init() { userloginhistoryFields := schema.UserLoginHistory{}.Fields() _ = userloginhistoryFields // userloginhistoryDescCreatedAt is the schema descriptor for created_at field. - userloginhistoryDescCreatedAt := userloginhistoryFields[10].Descriptor() + userloginhistoryDescCreatedAt := userloginhistoryFields[12].Descriptor() // userloginhistory.DefaultCreatedAt holds the default value on creation for the created_at field. userloginhistory.DefaultCreatedAt = userloginhistoryDescCreatedAt.Default.(func() time.Time) } diff --git a/backend/db/user/user.go b/backend/db/user/user.go index 79a65cc..80206be 100644 --- a/backend/db/user/user.go +++ b/backend/db/user/user.go @@ -50,7 +50,7 @@ const ( // It exists in this package in order to avoid circular dependency with the "userloginhistory" package. LoginHistoriesInverseTable = "user_login_histories" // LoginHistoriesColumn is the table column denoting the login_histories relation/edge. - LoginHistoriesColumn = "user_login_histories" + LoginHistoriesColumn = "user_id" // ModelsTable is the table that holds the models relation/edge. ModelsTable = "models" // ModelsInverseTable is the table name for the Model entity. diff --git a/backend/db/user_query.go b/backend/db/user_query.go index 2512f73..2004c2a 100644 --- a/backend/db/user_query.go +++ b/backend/db/user_query.go @@ -552,7 +552,9 @@ func (uq *UserQuery) loadLoginHistories(ctx context.Context, query *UserLoginHis init(nodes[i]) } } - query.withFKs = true + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(userloginhistory.FieldUserID) + } query.Where(predicate.UserLoginHistory(func(s *sql.Selector) { s.Where(sql.InValues(s.C(user.LoginHistoriesColumn), fks...)) })) @@ -561,13 +563,10 @@ func (uq *UserQuery) loadLoginHistories(ctx context.Context, query *UserLoginHis return err } for _, n := range neighbors { - fk := n.user_login_histories - if fk == nil { - return fmt.Errorf(`foreign-key "user_login_histories" is nil for node %v`, n.ID) - } - node, ok := nodeids[*fk] + fk := n.UserID + node, ok := nodeids[fk] if !ok { - return fmt.Errorf(`unexpected referenced foreign-key "user_login_histories" returned %v for node %v`, *fk, n.ID) + return fmt.Errorf(`unexpected referenced foreign-key "user_id" returned %v for node %v`, fk, n.ID) } assign(node, n) } diff --git a/backend/db/userloginhistory.go b/backend/db/userloginhistory.go index a183669..56a0b0c 100644 --- a/backend/db/userloginhistory.go +++ b/backend/db/userloginhistory.go @@ -9,6 +9,7 @@ import ( "entgo.io/ent" "entgo.io/ent/dialect/sql" + "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/userloginhistory" "github.com/google/uuid" @@ -35,15 +36,18 @@ type UserLoginHistory struct { Asn string `json:"asn,omitempty"` // ClientVersion holds the value of the "client_version" field. ClientVersion string `json:"client_version,omitempty"` - // Device holds the value of the "device" field. - Device string `json:"device,omitempty"` + // OsType holds the value of the "os_type" field. + OsType consts.OSType `json:"os_type,omitempty"` + // OsRelease holds the value of the "os_release" field. + OsRelease consts.OSRelease `json:"os_release,omitempty"` + // Hostname holds the value of the "hostname" field. + Hostname string `json:"hostname,omitempty"` // CreatedAt holds the value of the "created_at" field. CreatedAt time.Time `json:"created_at,omitempty"` // Edges holds the relations/edges for other nodes in the graph. // The values are being populated by the UserLoginHistoryQuery when eager-loading is set. - Edges UserLoginHistoryEdges `json:"edges"` - user_login_histories *uuid.UUID - selectValues sql.SelectValues + Edges UserLoginHistoryEdges `json:"edges"` + selectValues sql.SelectValues } // UserLoginHistoryEdges holds the relations/edges for other nodes in the graph. @@ -71,14 +75,12 @@ func (*UserLoginHistory) scanValues(columns []string) ([]any, error) { values := make([]any, len(columns)) for i := range columns { switch columns[i] { - case userloginhistory.FieldIP, userloginhistory.FieldCountry, userloginhistory.FieldProvince, userloginhistory.FieldCity, userloginhistory.FieldIsp, userloginhistory.FieldAsn, userloginhistory.FieldClientVersion, userloginhistory.FieldDevice: + case userloginhistory.FieldIP, userloginhistory.FieldCountry, userloginhistory.FieldProvince, userloginhistory.FieldCity, userloginhistory.FieldIsp, userloginhistory.FieldAsn, userloginhistory.FieldClientVersion, userloginhistory.FieldOsType, userloginhistory.FieldOsRelease, userloginhistory.FieldHostname: values[i] = new(sql.NullString) case userloginhistory.FieldCreatedAt: values[i] = new(sql.NullTime) case userloginhistory.FieldID, userloginhistory.FieldUserID: values[i] = new(uuid.UUID) - case userloginhistory.ForeignKeys[0]: // user_login_histories - values[i] = &sql.NullScanner{S: new(uuid.UUID)} default: values[i] = new(sql.UnknownType) } @@ -148,11 +150,23 @@ func (ulh *UserLoginHistory) assignValues(columns []string, values []any) error } else if value.Valid { ulh.ClientVersion = value.String } - case userloginhistory.FieldDevice: + case userloginhistory.FieldOsType: if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field device", values[i]) + return fmt.Errorf("unexpected type %T for field os_type", values[i]) } else if value.Valid { - ulh.Device = value.String + ulh.OsType = consts.OSType(value.String) + } + case userloginhistory.FieldOsRelease: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field os_release", values[i]) + } else if value.Valid { + ulh.OsRelease = consts.OSRelease(value.String) + } + case userloginhistory.FieldHostname: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field hostname", values[i]) + } else if value.Valid { + ulh.Hostname = value.String } case userloginhistory.FieldCreatedAt: if value, ok := values[i].(*sql.NullTime); !ok { @@ -160,13 +174,6 @@ func (ulh *UserLoginHistory) assignValues(columns []string, values []any) error } else if value.Valid { ulh.CreatedAt = value.Time } - case userloginhistory.ForeignKeys[0]: - if value, ok := values[i].(*sql.NullScanner); !ok { - return fmt.Errorf("unexpected type %T for field user_login_histories", values[i]) - } else if value.Valid { - ulh.user_login_histories = new(uuid.UUID) - *ulh.user_login_histories = *value.S.(*uuid.UUID) - } default: ulh.selectValues.Set(columns[i], values[i]) } @@ -232,8 +239,14 @@ func (ulh *UserLoginHistory) String() string { builder.WriteString("client_version=") builder.WriteString(ulh.ClientVersion) builder.WriteString(", ") - builder.WriteString("device=") - builder.WriteString(ulh.Device) + builder.WriteString("os_type=") + builder.WriteString(fmt.Sprintf("%v", ulh.OsType)) + builder.WriteString(", ") + builder.WriteString("os_release=") + builder.WriteString(fmt.Sprintf("%v", ulh.OsRelease)) + builder.WriteString(", ") + builder.WriteString("hostname=") + builder.WriteString(ulh.Hostname) builder.WriteString(", ") builder.WriteString("created_at=") builder.WriteString(ulh.CreatedAt.Format(time.ANSIC)) diff --git a/backend/db/userloginhistory/userloginhistory.go b/backend/db/userloginhistory/userloginhistory.go index 2694c85..8a34fcf 100644 --- a/backend/db/userloginhistory/userloginhistory.go +++ b/backend/db/userloginhistory/userloginhistory.go @@ -30,8 +30,12 @@ const ( FieldAsn = "asn" // FieldClientVersion holds the string denoting the client_version field in the database. FieldClientVersion = "client_version" - // FieldDevice holds the string denoting the device field in the database. - FieldDevice = "device" + // FieldOsType holds the string denoting the os_type field in the database. + FieldOsType = "os_type" + // FieldOsRelease holds the string denoting the os_release field in the database. + FieldOsRelease = "os_release" + // FieldHostname holds the string denoting the hostname field in the database. + FieldHostname = "hostname" // FieldCreatedAt holds the string denoting the created_at field in the database. FieldCreatedAt = "created_at" // EdgeOwner holds the string denoting the owner edge name in mutations. @@ -44,7 +48,7 @@ const ( // It exists in this package in order to avoid circular dependency with the "user" package. OwnerInverseTable = "users" // OwnerColumn is the table column denoting the owner relation/edge. - OwnerColumn = "user_login_histories" + OwnerColumn = "user_id" ) // Columns holds all SQL columns for userloginhistory fields. @@ -58,16 +62,12 @@ var Columns = []string{ FieldIsp, FieldAsn, FieldClientVersion, - FieldDevice, + FieldOsType, + FieldOsRelease, + FieldHostname, FieldCreatedAt, } -// ForeignKeys holds the SQL foreign-keys that are owned by the "user_login_histories" -// table and are not defined as standalone fields in the schema. -var ForeignKeys = []string{ - "user_login_histories", -} - // ValidColumn reports if the column name is valid (part of the table columns). func ValidColumn(column string) bool { for i := range Columns { @@ -75,11 +75,6 @@ func ValidColumn(column string) bool { return true } } - for i := range ForeignKeys { - if column == ForeignKeys[i] { - return true - } - } return false } @@ -136,9 +131,19 @@ func ByClientVersion(opts ...sql.OrderTermOption) OrderOption { return sql.OrderByField(FieldClientVersion, opts...).ToFunc() } -// ByDevice orders the results by the device field. -func ByDevice(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldDevice, opts...).ToFunc() +// ByOsType orders the results by the os_type field. +func ByOsType(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldOsType, opts...).ToFunc() +} + +// ByOsRelease orders the results by the os_release field. +func ByOsRelease(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldOsRelease, opts...).ToFunc() +} + +// ByHostname orders the results by the hostname field. +func ByHostname(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldHostname, opts...).ToFunc() } // ByCreatedAt orders the results by the created_at field. diff --git a/backend/db/userloginhistory/where.go b/backend/db/userloginhistory/where.go index e603d6e..8e283ea 100644 --- a/backend/db/userloginhistory/where.go +++ b/backend/db/userloginhistory/where.go @@ -7,6 +7,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" + "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db/predicate" "github.com/google/uuid" ) @@ -96,9 +97,21 @@ func ClientVersion(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldEQ(FieldClientVersion, v)) } -// Device applies equality check predicate on the "device" field. It's identical to DeviceEQ. -func Device(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldEQ(FieldDevice, v)) +// OsType applies equality check predicate on the "os_type" field. It's identical to OsTypeEQ. +func OsType(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldEQ(FieldOsType, vc)) +} + +// OsRelease applies equality check predicate on the "os_release" field. It's identical to OsReleaseEQ. +func OsRelease(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldEQ(FieldOsRelease, vc)) +} + +// Hostname applies equality check predicate on the "hostname" field. It's identical to HostnameEQ. +func Hostname(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldEQ(FieldHostname, v)) } // CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. @@ -126,24 +139,14 @@ func UserIDNotIn(vs ...uuid.UUID) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldNotIn(FieldUserID, vs...)) } -// UserIDGT applies the GT predicate on the "user_id" field. -func UserIDGT(v uuid.UUID) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldGT(FieldUserID, v)) +// UserIDIsNil applies the IsNil predicate on the "user_id" field. +func UserIDIsNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIsNull(FieldUserID)) } -// UserIDGTE applies the GTE predicate on the "user_id" field. -func UserIDGTE(v uuid.UUID) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldGTE(FieldUserID, v)) -} - -// UserIDLT applies the LT predicate on the "user_id" field. -func UserIDLT(v uuid.UUID) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldLT(FieldUserID, v)) -} - -// UserIDLTE applies the LTE predicate on the "user_id" field. -func UserIDLTE(v uuid.UUID) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldLTE(FieldUserID, v)) +// UserIDNotNil applies the NotNil predicate on the "user_id" field. +func UserIDNotNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotNull(FieldUserID)) } // IPEQ applies the EQ predicate on the "ip" field. @@ -461,6 +464,16 @@ func IspHasSuffix(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldHasSuffix(FieldIsp, v)) } +// IspIsNil applies the IsNil predicate on the "isp" field. +func IspIsNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIsNull(FieldIsp)) +} + +// IspNotNil applies the NotNil predicate on the "isp" field. +func IspNotNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotNull(FieldIsp)) +} + // IspEqualFold applies the EqualFold predicate on the "isp" field. func IspEqualFold(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldEqualFold(FieldIsp, v)) @@ -526,6 +539,16 @@ func AsnHasSuffix(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldHasSuffix(FieldAsn, v)) } +// AsnIsNil applies the IsNil predicate on the "asn" field. +func AsnIsNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIsNull(FieldAsn)) +} + +// AsnNotNil applies the NotNil predicate on the "asn" field. +func AsnNotNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotNull(FieldAsn)) +} + // AsnEqualFold applies the EqualFold predicate on the "asn" field. func AsnEqualFold(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldEqualFold(FieldAsn, v)) @@ -591,6 +614,16 @@ func ClientVersionHasSuffix(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldHasSuffix(FieldClientVersion, v)) } +// ClientVersionIsNil applies the IsNil predicate on the "client_version" field. +func ClientVersionIsNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIsNull(FieldClientVersion)) +} + +// ClientVersionNotNil applies the NotNil predicate on the "client_version" field. +func ClientVersionNotNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotNull(FieldClientVersion)) +} + // ClientVersionEqualFold applies the EqualFold predicate on the "client_version" field. func ClientVersionEqualFold(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldEqualFold(FieldClientVersion, v)) @@ -601,69 +634,267 @@ func ClientVersionContainsFold(v string) predicate.UserLoginHistory { return predicate.UserLoginHistory(sql.FieldContainsFold(FieldClientVersion, v)) } -// DeviceEQ applies the EQ predicate on the "device" field. -func DeviceEQ(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldEQ(FieldDevice, v)) +// OsTypeEQ applies the EQ predicate on the "os_type" field. +func OsTypeEQ(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldEQ(FieldOsType, vc)) } -// DeviceNEQ applies the NEQ predicate on the "device" field. -func DeviceNEQ(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldNEQ(FieldDevice, v)) +// OsTypeNEQ applies the NEQ predicate on the "os_type" field. +func OsTypeNEQ(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldNEQ(FieldOsType, vc)) } -// DeviceIn applies the In predicate on the "device" field. -func DeviceIn(vs ...string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldIn(FieldDevice, vs...)) +// OsTypeIn applies the In predicate on the "os_type" field. +func OsTypeIn(vs ...consts.OSType) predicate.UserLoginHistory { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.UserLoginHistory(sql.FieldIn(FieldOsType, v...)) } -// DeviceNotIn applies the NotIn predicate on the "device" field. -func DeviceNotIn(vs ...string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldNotIn(FieldDevice, vs...)) +// OsTypeNotIn applies the NotIn predicate on the "os_type" field. +func OsTypeNotIn(vs ...consts.OSType) predicate.UserLoginHistory { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.UserLoginHistory(sql.FieldNotIn(FieldOsType, v...)) } -// DeviceGT applies the GT predicate on the "device" field. -func DeviceGT(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldGT(FieldDevice, v)) +// OsTypeGT applies the GT predicate on the "os_type" field. +func OsTypeGT(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldGT(FieldOsType, vc)) } -// DeviceGTE applies the GTE predicate on the "device" field. -func DeviceGTE(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldGTE(FieldDevice, v)) +// OsTypeGTE applies the GTE predicate on the "os_type" field. +func OsTypeGTE(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldGTE(FieldOsType, vc)) } -// DeviceLT applies the LT predicate on the "device" field. -func DeviceLT(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldLT(FieldDevice, v)) +// OsTypeLT applies the LT predicate on the "os_type" field. +func OsTypeLT(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldLT(FieldOsType, vc)) } -// DeviceLTE applies the LTE predicate on the "device" field. -func DeviceLTE(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldLTE(FieldDevice, v)) +// OsTypeLTE applies the LTE predicate on the "os_type" field. +func OsTypeLTE(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldLTE(FieldOsType, vc)) } -// DeviceContains applies the Contains predicate on the "device" field. -func DeviceContains(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldContains(FieldDevice, v)) +// OsTypeContains applies the Contains predicate on the "os_type" field. +func OsTypeContains(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldContains(FieldOsType, vc)) } -// DeviceHasPrefix applies the HasPrefix predicate on the "device" field. -func DeviceHasPrefix(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldHasPrefix(FieldDevice, v)) +// OsTypeHasPrefix applies the HasPrefix predicate on the "os_type" field. +func OsTypeHasPrefix(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldHasPrefix(FieldOsType, vc)) } -// DeviceHasSuffix applies the HasSuffix predicate on the "device" field. -func DeviceHasSuffix(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldHasSuffix(FieldDevice, v)) +// OsTypeHasSuffix applies the HasSuffix predicate on the "os_type" field. +func OsTypeHasSuffix(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldHasSuffix(FieldOsType, vc)) } -// DeviceEqualFold applies the EqualFold predicate on the "device" field. -func DeviceEqualFold(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldEqualFold(FieldDevice, v)) +// OsTypeIsNil applies the IsNil predicate on the "os_type" field. +func OsTypeIsNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIsNull(FieldOsType)) } -// DeviceContainsFold applies the ContainsFold predicate on the "device" field. -func DeviceContainsFold(v string) predicate.UserLoginHistory { - return predicate.UserLoginHistory(sql.FieldContainsFold(FieldDevice, v)) +// OsTypeNotNil applies the NotNil predicate on the "os_type" field. +func OsTypeNotNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotNull(FieldOsType)) +} + +// OsTypeEqualFold applies the EqualFold predicate on the "os_type" field. +func OsTypeEqualFold(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldEqualFold(FieldOsType, vc)) +} + +// OsTypeContainsFold applies the ContainsFold predicate on the "os_type" field. +func OsTypeContainsFold(v consts.OSType) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldContainsFold(FieldOsType, vc)) +} + +// OsReleaseEQ applies the EQ predicate on the "os_release" field. +func OsReleaseEQ(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldEQ(FieldOsRelease, vc)) +} + +// OsReleaseNEQ applies the NEQ predicate on the "os_release" field. +func OsReleaseNEQ(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldNEQ(FieldOsRelease, vc)) +} + +// OsReleaseIn applies the In predicate on the "os_release" field. +func OsReleaseIn(vs ...consts.OSRelease) predicate.UserLoginHistory { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.UserLoginHistory(sql.FieldIn(FieldOsRelease, v...)) +} + +// OsReleaseNotIn applies the NotIn predicate on the "os_release" field. +func OsReleaseNotIn(vs ...consts.OSRelease) predicate.UserLoginHistory { + v := make([]any, len(vs)) + for i := range v { + v[i] = string(vs[i]) + } + return predicate.UserLoginHistory(sql.FieldNotIn(FieldOsRelease, v...)) +} + +// OsReleaseGT applies the GT predicate on the "os_release" field. +func OsReleaseGT(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldGT(FieldOsRelease, vc)) +} + +// OsReleaseGTE applies the GTE predicate on the "os_release" field. +func OsReleaseGTE(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldGTE(FieldOsRelease, vc)) +} + +// OsReleaseLT applies the LT predicate on the "os_release" field. +func OsReleaseLT(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldLT(FieldOsRelease, vc)) +} + +// OsReleaseLTE applies the LTE predicate on the "os_release" field. +func OsReleaseLTE(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldLTE(FieldOsRelease, vc)) +} + +// OsReleaseContains applies the Contains predicate on the "os_release" field. +func OsReleaseContains(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldContains(FieldOsRelease, vc)) +} + +// OsReleaseHasPrefix applies the HasPrefix predicate on the "os_release" field. +func OsReleaseHasPrefix(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldHasPrefix(FieldOsRelease, vc)) +} + +// OsReleaseHasSuffix applies the HasSuffix predicate on the "os_release" field. +func OsReleaseHasSuffix(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldHasSuffix(FieldOsRelease, vc)) +} + +// OsReleaseIsNil applies the IsNil predicate on the "os_release" field. +func OsReleaseIsNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIsNull(FieldOsRelease)) +} + +// OsReleaseNotNil applies the NotNil predicate on the "os_release" field. +func OsReleaseNotNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotNull(FieldOsRelease)) +} + +// OsReleaseEqualFold applies the EqualFold predicate on the "os_release" field. +func OsReleaseEqualFold(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldEqualFold(FieldOsRelease, vc)) +} + +// OsReleaseContainsFold applies the ContainsFold predicate on the "os_release" field. +func OsReleaseContainsFold(v consts.OSRelease) predicate.UserLoginHistory { + vc := string(v) + return predicate.UserLoginHistory(sql.FieldContainsFold(FieldOsRelease, vc)) +} + +// HostnameEQ applies the EQ predicate on the "hostname" field. +func HostnameEQ(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldEQ(FieldHostname, v)) +} + +// HostnameNEQ applies the NEQ predicate on the "hostname" field. +func HostnameNEQ(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNEQ(FieldHostname, v)) +} + +// HostnameIn applies the In predicate on the "hostname" field. +func HostnameIn(vs ...string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIn(FieldHostname, vs...)) +} + +// HostnameNotIn applies the NotIn predicate on the "hostname" field. +func HostnameNotIn(vs ...string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotIn(FieldHostname, vs...)) +} + +// HostnameGT applies the GT predicate on the "hostname" field. +func HostnameGT(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldGT(FieldHostname, v)) +} + +// HostnameGTE applies the GTE predicate on the "hostname" field. +func HostnameGTE(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldGTE(FieldHostname, v)) +} + +// HostnameLT applies the LT predicate on the "hostname" field. +func HostnameLT(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldLT(FieldHostname, v)) +} + +// HostnameLTE applies the LTE predicate on the "hostname" field. +func HostnameLTE(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldLTE(FieldHostname, v)) +} + +// HostnameContains applies the Contains predicate on the "hostname" field. +func HostnameContains(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldContains(FieldHostname, v)) +} + +// HostnameHasPrefix applies the HasPrefix predicate on the "hostname" field. +func HostnameHasPrefix(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldHasPrefix(FieldHostname, v)) +} + +// HostnameHasSuffix applies the HasSuffix predicate on the "hostname" field. +func HostnameHasSuffix(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldHasSuffix(FieldHostname, v)) +} + +// HostnameIsNil applies the IsNil predicate on the "hostname" field. +func HostnameIsNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldIsNull(FieldHostname)) +} + +// HostnameNotNil applies the NotNil predicate on the "hostname" field. +func HostnameNotNil() predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldNotNull(FieldHostname)) +} + +// HostnameEqualFold applies the EqualFold predicate on the "hostname" field. +func HostnameEqualFold(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldEqualFold(FieldHostname, v)) +} + +// HostnameContainsFold applies the ContainsFold predicate on the "hostname" field. +func HostnameContainsFold(v string) predicate.UserLoginHistory { + return predicate.UserLoginHistory(sql.FieldContainsFold(FieldHostname, v)) } // CreatedAtEQ applies the EQ predicate on the "created_at" field. diff --git a/backend/db/userloginhistory_create.go b/backend/db/userloginhistory_create.go index 94b0022..55e1a85 100644 --- a/backend/db/userloginhistory_create.go +++ b/backend/db/userloginhistory_create.go @@ -12,6 +12,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" + "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/userloginhistory" "github.com/google/uuid" @@ -31,6 +32,14 @@ func (ulhc *UserLoginHistoryCreate) SetUserID(u uuid.UUID) *UserLoginHistoryCrea return ulhc } +// SetNillableUserID sets the "user_id" field if the given value is not nil. +func (ulhc *UserLoginHistoryCreate) SetNillableUserID(u *uuid.UUID) *UserLoginHistoryCreate { + if u != nil { + ulhc.SetUserID(*u) + } + return ulhc +} + // SetIP sets the "ip" field. func (ulhc *UserLoginHistoryCreate) SetIP(s string) *UserLoginHistoryCreate { ulhc.mutation.SetIP(s) @@ -61,21 +70,81 @@ func (ulhc *UserLoginHistoryCreate) SetIsp(s string) *UserLoginHistoryCreate { return ulhc } +// SetNillableIsp sets the "isp" field if the given value is not nil. +func (ulhc *UserLoginHistoryCreate) SetNillableIsp(s *string) *UserLoginHistoryCreate { + if s != nil { + ulhc.SetIsp(*s) + } + return ulhc +} + // SetAsn sets the "asn" field. func (ulhc *UserLoginHistoryCreate) SetAsn(s string) *UserLoginHistoryCreate { ulhc.mutation.SetAsn(s) return ulhc } +// SetNillableAsn sets the "asn" field if the given value is not nil. +func (ulhc *UserLoginHistoryCreate) SetNillableAsn(s *string) *UserLoginHistoryCreate { + if s != nil { + ulhc.SetAsn(*s) + } + return ulhc +} + // SetClientVersion sets the "client_version" field. func (ulhc *UserLoginHistoryCreate) SetClientVersion(s string) *UserLoginHistoryCreate { ulhc.mutation.SetClientVersion(s) return ulhc } -// SetDevice sets the "device" field. -func (ulhc *UserLoginHistoryCreate) SetDevice(s string) *UserLoginHistoryCreate { - ulhc.mutation.SetDevice(s) +// SetNillableClientVersion sets the "client_version" field if the given value is not nil. +func (ulhc *UserLoginHistoryCreate) SetNillableClientVersion(s *string) *UserLoginHistoryCreate { + if s != nil { + ulhc.SetClientVersion(*s) + } + return ulhc +} + +// SetOsType sets the "os_type" field. +func (ulhc *UserLoginHistoryCreate) SetOsType(ct consts.OSType) *UserLoginHistoryCreate { + ulhc.mutation.SetOsType(ct) + return ulhc +} + +// SetNillableOsType sets the "os_type" field if the given value is not nil. +func (ulhc *UserLoginHistoryCreate) SetNillableOsType(ct *consts.OSType) *UserLoginHistoryCreate { + if ct != nil { + ulhc.SetOsType(*ct) + } + return ulhc +} + +// SetOsRelease sets the "os_release" field. +func (ulhc *UserLoginHistoryCreate) SetOsRelease(cr consts.OSRelease) *UserLoginHistoryCreate { + ulhc.mutation.SetOsRelease(cr) + return ulhc +} + +// SetNillableOsRelease sets the "os_release" field if the given value is not nil. +func (ulhc *UserLoginHistoryCreate) SetNillableOsRelease(cr *consts.OSRelease) *UserLoginHistoryCreate { + if cr != nil { + ulhc.SetOsRelease(*cr) + } + return ulhc +} + +// SetHostname sets the "hostname" field. +func (ulhc *UserLoginHistoryCreate) SetHostname(s string) *UserLoginHistoryCreate { + ulhc.mutation.SetHostname(s) + return ulhc +} + +// SetNillableHostname sets the "hostname" field if the given value is not nil. +func (ulhc *UserLoginHistoryCreate) SetNillableHostname(s *string) *UserLoginHistoryCreate { + if s != nil { + ulhc.SetHostname(*s) + } return ulhc } @@ -161,9 +230,6 @@ func (ulhc *UserLoginHistoryCreate) defaults() { // check runs all checks and user-defined validators on the builder. func (ulhc *UserLoginHistoryCreate) check() error { - if _, ok := ulhc.mutation.UserID(); !ok { - return &ValidationError{Name: "user_id", err: errors.New(`db: missing required field "UserLoginHistory.user_id"`)} - } if _, ok := ulhc.mutation.IP(); !ok { return &ValidationError{Name: "ip", err: errors.New(`db: missing required field "UserLoginHistory.ip"`)} } @@ -176,18 +242,6 @@ func (ulhc *UserLoginHistoryCreate) check() error { if _, ok := ulhc.mutation.City(); !ok { return &ValidationError{Name: "city", err: errors.New(`db: missing required field "UserLoginHistory.city"`)} } - if _, ok := ulhc.mutation.Isp(); !ok { - return &ValidationError{Name: "isp", err: errors.New(`db: missing required field "UserLoginHistory.isp"`)} - } - if _, ok := ulhc.mutation.Asn(); !ok { - return &ValidationError{Name: "asn", err: errors.New(`db: missing required field "UserLoginHistory.asn"`)} - } - if _, ok := ulhc.mutation.ClientVersion(); !ok { - return &ValidationError{Name: "client_version", err: errors.New(`db: missing required field "UserLoginHistory.client_version"`)} - } - if _, ok := ulhc.mutation.Device(); !ok { - return &ValidationError{Name: "device", err: errors.New(`db: missing required field "UserLoginHistory.device"`)} - } if _, ok := ulhc.mutation.CreatedAt(); !ok { return &ValidationError{Name: "created_at", err: errors.New(`db: missing required field "UserLoginHistory.created_at"`)} } @@ -227,10 +281,6 @@ func (ulhc *UserLoginHistoryCreate) createSpec() (*UserLoginHistory, *sqlgraph.C _node.ID = id _spec.ID.Value = &id } - if value, ok := ulhc.mutation.UserID(); ok { - _spec.SetField(userloginhistory.FieldUserID, field.TypeUUID, value) - _node.UserID = value - } if value, ok := ulhc.mutation.IP(); ok { _spec.SetField(userloginhistory.FieldIP, field.TypeString, value) _node.IP = value @@ -259,9 +309,17 @@ func (ulhc *UserLoginHistoryCreate) createSpec() (*UserLoginHistory, *sqlgraph.C _spec.SetField(userloginhistory.FieldClientVersion, field.TypeString, value) _node.ClientVersion = value } - if value, ok := ulhc.mutation.Device(); ok { - _spec.SetField(userloginhistory.FieldDevice, field.TypeString, value) - _node.Device = value + if value, ok := ulhc.mutation.OsType(); ok { + _spec.SetField(userloginhistory.FieldOsType, field.TypeString, value) + _node.OsType = value + } + if value, ok := ulhc.mutation.OsRelease(); ok { + _spec.SetField(userloginhistory.FieldOsRelease, field.TypeString, value) + _node.OsRelease = value + } + if value, ok := ulhc.mutation.Hostname(); ok { + _spec.SetField(userloginhistory.FieldHostname, field.TypeString, value) + _node.Hostname = value } if value, ok := ulhc.mutation.CreatedAt(); ok { _spec.SetField(userloginhistory.FieldCreatedAt, field.TypeTime, value) @@ -281,7 +339,7 @@ func (ulhc *UserLoginHistoryCreate) createSpec() (*UserLoginHistory, *sqlgraph.C for _, k := range nodes { edge.Target.Nodes = append(edge.Target.Nodes, k) } - _node.user_login_histories = &nodes[0] + _node.UserID = nodes[0] _spec.Edges = append(_spec.Edges, edge) } return _node, _spec @@ -348,6 +406,12 @@ func (u *UserLoginHistoryUpsert) UpdateUserID() *UserLoginHistoryUpsert { return u } +// ClearUserID clears the value of the "user_id" field. +func (u *UserLoginHistoryUpsert) ClearUserID() *UserLoginHistoryUpsert { + u.SetNull(userloginhistory.FieldUserID) + return u +} + // SetIP sets the "ip" field. func (u *UserLoginHistoryUpsert) SetIP(v string) *UserLoginHistoryUpsert { u.Set(userloginhistory.FieldIP, v) @@ -408,6 +472,12 @@ func (u *UserLoginHistoryUpsert) UpdateIsp() *UserLoginHistoryUpsert { return u } +// ClearIsp clears the value of the "isp" field. +func (u *UserLoginHistoryUpsert) ClearIsp() *UserLoginHistoryUpsert { + u.SetNull(userloginhistory.FieldIsp) + return u +} + // SetAsn sets the "asn" field. func (u *UserLoginHistoryUpsert) SetAsn(v string) *UserLoginHistoryUpsert { u.Set(userloginhistory.FieldAsn, v) @@ -420,6 +490,12 @@ func (u *UserLoginHistoryUpsert) UpdateAsn() *UserLoginHistoryUpsert { return u } +// ClearAsn clears the value of the "asn" field. +func (u *UserLoginHistoryUpsert) ClearAsn() *UserLoginHistoryUpsert { + u.SetNull(userloginhistory.FieldAsn) + return u +} + // SetClientVersion sets the "client_version" field. func (u *UserLoginHistoryUpsert) SetClientVersion(v string) *UserLoginHistoryUpsert { u.Set(userloginhistory.FieldClientVersion, v) @@ -432,15 +508,63 @@ func (u *UserLoginHistoryUpsert) UpdateClientVersion() *UserLoginHistoryUpsert { return u } -// SetDevice sets the "device" field. -func (u *UserLoginHistoryUpsert) SetDevice(v string) *UserLoginHistoryUpsert { - u.Set(userloginhistory.FieldDevice, v) +// ClearClientVersion clears the value of the "client_version" field. +func (u *UserLoginHistoryUpsert) ClearClientVersion() *UserLoginHistoryUpsert { + u.SetNull(userloginhistory.FieldClientVersion) return u } -// UpdateDevice sets the "device" field to the value that was provided on create. -func (u *UserLoginHistoryUpsert) UpdateDevice() *UserLoginHistoryUpsert { - u.SetExcluded(userloginhistory.FieldDevice) +// SetOsType sets the "os_type" field. +func (u *UserLoginHistoryUpsert) SetOsType(v consts.OSType) *UserLoginHistoryUpsert { + u.Set(userloginhistory.FieldOsType, v) + return u +} + +// UpdateOsType sets the "os_type" field to the value that was provided on create. +func (u *UserLoginHistoryUpsert) UpdateOsType() *UserLoginHistoryUpsert { + u.SetExcluded(userloginhistory.FieldOsType) + return u +} + +// ClearOsType clears the value of the "os_type" field. +func (u *UserLoginHistoryUpsert) ClearOsType() *UserLoginHistoryUpsert { + u.SetNull(userloginhistory.FieldOsType) + return u +} + +// SetOsRelease sets the "os_release" field. +func (u *UserLoginHistoryUpsert) SetOsRelease(v consts.OSRelease) *UserLoginHistoryUpsert { + u.Set(userloginhistory.FieldOsRelease, v) + return u +} + +// UpdateOsRelease sets the "os_release" field to the value that was provided on create. +func (u *UserLoginHistoryUpsert) UpdateOsRelease() *UserLoginHistoryUpsert { + u.SetExcluded(userloginhistory.FieldOsRelease) + return u +} + +// ClearOsRelease clears the value of the "os_release" field. +func (u *UserLoginHistoryUpsert) ClearOsRelease() *UserLoginHistoryUpsert { + u.SetNull(userloginhistory.FieldOsRelease) + return u +} + +// SetHostname sets the "hostname" field. +func (u *UserLoginHistoryUpsert) SetHostname(v string) *UserLoginHistoryUpsert { + u.Set(userloginhistory.FieldHostname, v) + return u +} + +// UpdateHostname sets the "hostname" field to the value that was provided on create. +func (u *UserLoginHistoryUpsert) UpdateHostname() *UserLoginHistoryUpsert { + u.SetExcluded(userloginhistory.FieldHostname) + return u +} + +// ClearHostname clears the value of the "hostname" field. +func (u *UserLoginHistoryUpsert) ClearHostname() *UserLoginHistoryUpsert { + u.SetNull(userloginhistory.FieldHostname) return u } @@ -518,6 +642,13 @@ func (u *UserLoginHistoryUpsertOne) UpdateUserID() *UserLoginHistoryUpsertOne { }) } +// ClearUserID clears the value of the "user_id" field. +func (u *UserLoginHistoryUpsertOne) ClearUserID() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearUserID() + }) +} + // SetIP sets the "ip" field. func (u *UserLoginHistoryUpsertOne) SetIP(v string) *UserLoginHistoryUpsertOne { return u.Update(func(s *UserLoginHistoryUpsert) { @@ -588,6 +719,13 @@ func (u *UserLoginHistoryUpsertOne) UpdateIsp() *UserLoginHistoryUpsertOne { }) } +// ClearIsp clears the value of the "isp" field. +func (u *UserLoginHistoryUpsertOne) ClearIsp() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearIsp() + }) +} + // SetAsn sets the "asn" field. func (u *UserLoginHistoryUpsertOne) SetAsn(v string) *UserLoginHistoryUpsertOne { return u.Update(func(s *UserLoginHistoryUpsert) { @@ -602,6 +740,13 @@ func (u *UserLoginHistoryUpsertOne) UpdateAsn() *UserLoginHistoryUpsertOne { }) } +// ClearAsn clears the value of the "asn" field. +func (u *UserLoginHistoryUpsertOne) ClearAsn() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearAsn() + }) +} + // SetClientVersion sets the "client_version" field. func (u *UserLoginHistoryUpsertOne) SetClientVersion(v string) *UserLoginHistoryUpsertOne { return u.Update(func(s *UserLoginHistoryUpsert) { @@ -616,17 +761,73 @@ func (u *UserLoginHistoryUpsertOne) UpdateClientVersion() *UserLoginHistoryUpser }) } -// SetDevice sets the "device" field. -func (u *UserLoginHistoryUpsertOne) SetDevice(v string) *UserLoginHistoryUpsertOne { +// ClearClientVersion clears the value of the "client_version" field. +func (u *UserLoginHistoryUpsertOne) ClearClientVersion() *UserLoginHistoryUpsertOne { return u.Update(func(s *UserLoginHistoryUpsert) { - s.SetDevice(v) + s.ClearClientVersion() }) } -// UpdateDevice sets the "device" field to the value that was provided on create. -func (u *UserLoginHistoryUpsertOne) UpdateDevice() *UserLoginHistoryUpsertOne { +// SetOsType sets the "os_type" field. +func (u *UserLoginHistoryUpsertOne) SetOsType(v consts.OSType) *UserLoginHistoryUpsertOne { return u.Update(func(s *UserLoginHistoryUpsert) { - s.UpdateDevice() + s.SetOsType(v) + }) +} + +// UpdateOsType sets the "os_type" field to the value that was provided on create. +func (u *UserLoginHistoryUpsertOne) UpdateOsType() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.UpdateOsType() + }) +} + +// ClearOsType clears the value of the "os_type" field. +func (u *UserLoginHistoryUpsertOne) ClearOsType() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearOsType() + }) +} + +// SetOsRelease sets the "os_release" field. +func (u *UserLoginHistoryUpsertOne) SetOsRelease(v consts.OSRelease) *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.SetOsRelease(v) + }) +} + +// UpdateOsRelease sets the "os_release" field to the value that was provided on create. +func (u *UserLoginHistoryUpsertOne) UpdateOsRelease() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.UpdateOsRelease() + }) +} + +// ClearOsRelease clears the value of the "os_release" field. +func (u *UserLoginHistoryUpsertOne) ClearOsRelease() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearOsRelease() + }) +} + +// SetHostname sets the "hostname" field. +func (u *UserLoginHistoryUpsertOne) SetHostname(v string) *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.SetHostname(v) + }) +} + +// UpdateHostname sets the "hostname" field to the value that was provided on create. +func (u *UserLoginHistoryUpsertOne) UpdateHostname() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.UpdateHostname() + }) +} + +// ClearHostname clears the value of the "hostname" field. +func (u *UserLoginHistoryUpsertOne) ClearHostname() *UserLoginHistoryUpsertOne { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearHostname() }) } @@ -873,6 +1074,13 @@ func (u *UserLoginHistoryUpsertBulk) UpdateUserID() *UserLoginHistoryUpsertBulk }) } +// ClearUserID clears the value of the "user_id" field. +func (u *UserLoginHistoryUpsertBulk) ClearUserID() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearUserID() + }) +} + // SetIP sets the "ip" field. func (u *UserLoginHistoryUpsertBulk) SetIP(v string) *UserLoginHistoryUpsertBulk { return u.Update(func(s *UserLoginHistoryUpsert) { @@ -943,6 +1151,13 @@ func (u *UserLoginHistoryUpsertBulk) UpdateIsp() *UserLoginHistoryUpsertBulk { }) } +// ClearIsp clears the value of the "isp" field. +func (u *UserLoginHistoryUpsertBulk) ClearIsp() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearIsp() + }) +} + // SetAsn sets the "asn" field. func (u *UserLoginHistoryUpsertBulk) SetAsn(v string) *UserLoginHistoryUpsertBulk { return u.Update(func(s *UserLoginHistoryUpsert) { @@ -957,6 +1172,13 @@ func (u *UserLoginHistoryUpsertBulk) UpdateAsn() *UserLoginHistoryUpsertBulk { }) } +// ClearAsn clears the value of the "asn" field. +func (u *UserLoginHistoryUpsertBulk) ClearAsn() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearAsn() + }) +} + // SetClientVersion sets the "client_version" field. func (u *UserLoginHistoryUpsertBulk) SetClientVersion(v string) *UserLoginHistoryUpsertBulk { return u.Update(func(s *UserLoginHistoryUpsert) { @@ -971,17 +1193,73 @@ func (u *UserLoginHistoryUpsertBulk) UpdateClientVersion() *UserLoginHistoryUpse }) } -// SetDevice sets the "device" field. -func (u *UserLoginHistoryUpsertBulk) SetDevice(v string) *UserLoginHistoryUpsertBulk { +// ClearClientVersion clears the value of the "client_version" field. +func (u *UserLoginHistoryUpsertBulk) ClearClientVersion() *UserLoginHistoryUpsertBulk { return u.Update(func(s *UserLoginHistoryUpsert) { - s.SetDevice(v) + s.ClearClientVersion() }) } -// UpdateDevice sets the "device" field to the value that was provided on create. -func (u *UserLoginHistoryUpsertBulk) UpdateDevice() *UserLoginHistoryUpsertBulk { +// SetOsType sets the "os_type" field. +func (u *UserLoginHistoryUpsertBulk) SetOsType(v consts.OSType) *UserLoginHistoryUpsertBulk { return u.Update(func(s *UserLoginHistoryUpsert) { - s.UpdateDevice() + s.SetOsType(v) + }) +} + +// UpdateOsType sets the "os_type" field to the value that was provided on create. +func (u *UserLoginHistoryUpsertBulk) UpdateOsType() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.UpdateOsType() + }) +} + +// ClearOsType clears the value of the "os_type" field. +func (u *UserLoginHistoryUpsertBulk) ClearOsType() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearOsType() + }) +} + +// SetOsRelease sets the "os_release" field. +func (u *UserLoginHistoryUpsertBulk) SetOsRelease(v consts.OSRelease) *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.SetOsRelease(v) + }) +} + +// UpdateOsRelease sets the "os_release" field to the value that was provided on create. +func (u *UserLoginHistoryUpsertBulk) UpdateOsRelease() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.UpdateOsRelease() + }) +} + +// ClearOsRelease clears the value of the "os_release" field. +func (u *UserLoginHistoryUpsertBulk) ClearOsRelease() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearOsRelease() + }) +} + +// SetHostname sets the "hostname" field. +func (u *UserLoginHistoryUpsertBulk) SetHostname(v string) *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.SetHostname(v) + }) +} + +// UpdateHostname sets the "hostname" field to the value that was provided on create. +func (u *UserLoginHistoryUpsertBulk) UpdateHostname() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.UpdateHostname() + }) +} + +// ClearHostname clears the value of the "hostname" field. +func (u *UserLoginHistoryUpsertBulk) ClearHostname() *UserLoginHistoryUpsertBulk { + return u.Update(func(s *UserLoginHistoryUpsert) { + s.ClearHostname() }) } diff --git a/backend/db/userloginhistory_query.go b/backend/db/userloginhistory_query.go index 5a1d192..d2b31b3 100644 --- a/backend/db/userloginhistory_query.go +++ b/backend/db/userloginhistory_query.go @@ -26,7 +26,6 @@ type UserLoginHistoryQuery struct { inters []Interceptor predicates []predicate.UserLoginHistory withOwner *UserQuery - withFKs bool modifiers []func(*sql.Selector) // intermediate query (i.e. traversal path). sql *sql.Selector @@ -374,18 +373,11 @@ func (ulhq *UserLoginHistoryQuery) prepareQuery(ctx context.Context) error { func (ulhq *UserLoginHistoryQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*UserLoginHistory, error) { var ( nodes = []*UserLoginHistory{} - withFKs = ulhq.withFKs _spec = ulhq.querySpec() loadedTypes = [1]bool{ ulhq.withOwner != nil, } ) - if ulhq.withOwner != nil { - withFKs = true - } - if withFKs { - _spec.Node.Columns = append(_spec.Node.Columns, userloginhistory.ForeignKeys...) - } _spec.ScanValues = func(columns []string) ([]any, error) { return (*UserLoginHistory).scanValues(nil, columns) } @@ -420,10 +412,7 @@ func (ulhq *UserLoginHistoryQuery) loadOwner(ctx context.Context, query *UserQue ids := make([]uuid.UUID, 0, len(nodes)) nodeids := make(map[uuid.UUID][]*UserLoginHistory) for i := range nodes { - if nodes[i].user_login_histories == nil { - continue - } - fk := *nodes[i].user_login_histories + fk := nodes[i].UserID if _, ok := nodeids[fk]; !ok { ids = append(ids, fk) } @@ -440,7 +429,7 @@ func (ulhq *UserLoginHistoryQuery) loadOwner(ctx context.Context, query *UserQue for _, n := range neighbors { nodes, ok := nodeids[n.ID] if !ok { - return fmt.Errorf(`unexpected foreign-key "user_login_histories" returned %v`, n.ID) + return fmt.Errorf(`unexpected foreign-key "user_id" returned %v`, n.ID) } for i := range nodes { assign(nodes[i], n) @@ -477,6 +466,9 @@ func (ulhq *UserLoginHistoryQuery) querySpec() *sqlgraph.QuerySpec { _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) } } + if ulhq.withOwner != nil { + _spec.Node.AddColumnOnce(userloginhistory.FieldUserID) + } } if ps := ulhq.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { diff --git a/backend/db/userloginhistory_update.go b/backend/db/userloginhistory_update.go index a48522c..085a2aa 100644 --- a/backend/db/userloginhistory_update.go +++ b/backend/db/userloginhistory_update.go @@ -11,6 +11,7 @@ import ( "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" + "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db/predicate" "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/userloginhistory" @@ -45,6 +46,12 @@ func (ulhu *UserLoginHistoryUpdate) SetNillableUserID(u *uuid.UUID) *UserLoginHi return ulhu } +// ClearUserID clears the value of the "user_id" field. +func (ulhu *UserLoginHistoryUpdate) ClearUserID() *UserLoginHistoryUpdate { + ulhu.mutation.ClearUserID() + return ulhu +} + // SetIP sets the "ip" field. func (ulhu *UserLoginHistoryUpdate) SetIP(s string) *UserLoginHistoryUpdate { ulhu.mutation.SetIP(s) @@ -115,6 +122,12 @@ func (ulhu *UserLoginHistoryUpdate) SetNillableIsp(s *string) *UserLoginHistoryU return ulhu } +// ClearIsp clears the value of the "isp" field. +func (ulhu *UserLoginHistoryUpdate) ClearIsp() *UserLoginHistoryUpdate { + ulhu.mutation.ClearIsp() + return ulhu +} + // SetAsn sets the "asn" field. func (ulhu *UserLoginHistoryUpdate) SetAsn(s string) *UserLoginHistoryUpdate { ulhu.mutation.SetAsn(s) @@ -129,6 +142,12 @@ func (ulhu *UserLoginHistoryUpdate) SetNillableAsn(s *string) *UserLoginHistoryU return ulhu } +// ClearAsn clears the value of the "asn" field. +func (ulhu *UserLoginHistoryUpdate) ClearAsn() *UserLoginHistoryUpdate { + ulhu.mutation.ClearAsn() + return ulhu +} + // SetClientVersion sets the "client_version" field. func (ulhu *UserLoginHistoryUpdate) SetClientVersion(s string) *UserLoginHistoryUpdate { ulhu.mutation.SetClientVersion(s) @@ -143,20 +162,72 @@ func (ulhu *UserLoginHistoryUpdate) SetNillableClientVersion(s *string) *UserLog return ulhu } -// SetDevice sets the "device" field. -func (ulhu *UserLoginHistoryUpdate) SetDevice(s string) *UserLoginHistoryUpdate { - ulhu.mutation.SetDevice(s) +// ClearClientVersion clears the value of the "client_version" field. +func (ulhu *UserLoginHistoryUpdate) ClearClientVersion() *UserLoginHistoryUpdate { + ulhu.mutation.ClearClientVersion() return ulhu } -// SetNillableDevice sets the "device" field if the given value is not nil. -func (ulhu *UserLoginHistoryUpdate) SetNillableDevice(s *string) *UserLoginHistoryUpdate { - if s != nil { - ulhu.SetDevice(*s) +// SetOsType sets the "os_type" field. +func (ulhu *UserLoginHistoryUpdate) SetOsType(ct consts.OSType) *UserLoginHistoryUpdate { + ulhu.mutation.SetOsType(ct) + return ulhu +} + +// SetNillableOsType sets the "os_type" field if the given value is not nil. +func (ulhu *UserLoginHistoryUpdate) SetNillableOsType(ct *consts.OSType) *UserLoginHistoryUpdate { + if ct != nil { + ulhu.SetOsType(*ct) } return ulhu } +// ClearOsType clears the value of the "os_type" field. +func (ulhu *UserLoginHistoryUpdate) ClearOsType() *UserLoginHistoryUpdate { + ulhu.mutation.ClearOsType() + return ulhu +} + +// SetOsRelease sets the "os_release" field. +func (ulhu *UserLoginHistoryUpdate) SetOsRelease(cr consts.OSRelease) *UserLoginHistoryUpdate { + ulhu.mutation.SetOsRelease(cr) + return ulhu +} + +// SetNillableOsRelease sets the "os_release" field if the given value is not nil. +func (ulhu *UserLoginHistoryUpdate) SetNillableOsRelease(cr *consts.OSRelease) *UserLoginHistoryUpdate { + if cr != nil { + ulhu.SetOsRelease(*cr) + } + return ulhu +} + +// ClearOsRelease clears the value of the "os_release" field. +func (ulhu *UserLoginHistoryUpdate) ClearOsRelease() *UserLoginHistoryUpdate { + ulhu.mutation.ClearOsRelease() + return ulhu +} + +// SetHostname sets the "hostname" field. +func (ulhu *UserLoginHistoryUpdate) SetHostname(s string) *UserLoginHistoryUpdate { + ulhu.mutation.SetHostname(s) + return ulhu +} + +// SetNillableHostname sets the "hostname" field if the given value is not nil. +func (ulhu *UserLoginHistoryUpdate) SetNillableHostname(s *string) *UserLoginHistoryUpdate { + if s != nil { + ulhu.SetHostname(*s) + } + return ulhu +} + +// ClearHostname clears the value of the "hostname" field. +func (ulhu *UserLoginHistoryUpdate) ClearHostname() *UserLoginHistoryUpdate { + ulhu.mutation.ClearHostname() + return ulhu +} + // SetCreatedAt sets the "created_at" field. func (ulhu *UserLoginHistoryUpdate) SetCreatedAt(t time.Time) *UserLoginHistoryUpdate { ulhu.mutation.SetCreatedAt(t) @@ -243,9 +314,6 @@ func (ulhu *UserLoginHistoryUpdate) sqlSave(ctx context.Context) (n int, err err } } } - if value, ok := ulhu.mutation.UserID(); ok { - _spec.SetField(userloginhistory.FieldUserID, field.TypeUUID, value) - } if value, ok := ulhu.mutation.IP(); ok { _spec.SetField(userloginhistory.FieldIP, field.TypeString, value) } @@ -261,14 +329,38 @@ func (ulhu *UserLoginHistoryUpdate) sqlSave(ctx context.Context) (n int, err err if value, ok := ulhu.mutation.Isp(); ok { _spec.SetField(userloginhistory.FieldIsp, field.TypeString, value) } + if ulhu.mutation.IspCleared() { + _spec.ClearField(userloginhistory.FieldIsp, field.TypeString) + } if value, ok := ulhu.mutation.Asn(); ok { _spec.SetField(userloginhistory.FieldAsn, field.TypeString, value) } + if ulhu.mutation.AsnCleared() { + _spec.ClearField(userloginhistory.FieldAsn, field.TypeString) + } if value, ok := ulhu.mutation.ClientVersion(); ok { _spec.SetField(userloginhistory.FieldClientVersion, field.TypeString, value) } - if value, ok := ulhu.mutation.Device(); ok { - _spec.SetField(userloginhistory.FieldDevice, field.TypeString, value) + if ulhu.mutation.ClientVersionCleared() { + _spec.ClearField(userloginhistory.FieldClientVersion, field.TypeString) + } + if value, ok := ulhu.mutation.OsType(); ok { + _spec.SetField(userloginhistory.FieldOsType, field.TypeString, value) + } + if ulhu.mutation.OsTypeCleared() { + _spec.ClearField(userloginhistory.FieldOsType, field.TypeString) + } + if value, ok := ulhu.mutation.OsRelease(); ok { + _spec.SetField(userloginhistory.FieldOsRelease, field.TypeString, value) + } + if ulhu.mutation.OsReleaseCleared() { + _spec.ClearField(userloginhistory.FieldOsRelease, field.TypeString) + } + if value, ok := ulhu.mutation.Hostname(); ok { + _spec.SetField(userloginhistory.FieldHostname, field.TypeString, value) + } + if ulhu.mutation.HostnameCleared() { + _spec.ClearField(userloginhistory.FieldHostname, field.TypeString) } if value, ok := ulhu.mutation.CreatedAt(); ok { _spec.SetField(userloginhistory.FieldCreatedAt, field.TypeTime, value) @@ -338,6 +430,12 @@ func (ulhuo *UserLoginHistoryUpdateOne) SetNillableUserID(u *uuid.UUID) *UserLog return ulhuo } +// ClearUserID clears the value of the "user_id" field. +func (ulhuo *UserLoginHistoryUpdateOne) ClearUserID() *UserLoginHistoryUpdateOne { + ulhuo.mutation.ClearUserID() + return ulhuo +} + // SetIP sets the "ip" field. func (ulhuo *UserLoginHistoryUpdateOne) SetIP(s string) *UserLoginHistoryUpdateOne { ulhuo.mutation.SetIP(s) @@ -408,6 +506,12 @@ func (ulhuo *UserLoginHistoryUpdateOne) SetNillableIsp(s *string) *UserLoginHist return ulhuo } +// ClearIsp clears the value of the "isp" field. +func (ulhuo *UserLoginHistoryUpdateOne) ClearIsp() *UserLoginHistoryUpdateOne { + ulhuo.mutation.ClearIsp() + return ulhuo +} + // SetAsn sets the "asn" field. func (ulhuo *UserLoginHistoryUpdateOne) SetAsn(s string) *UserLoginHistoryUpdateOne { ulhuo.mutation.SetAsn(s) @@ -422,6 +526,12 @@ func (ulhuo *UserLoginHistoryUpdateOne) SetNillableAsn(s *string) *UserLoginHist return ulhuo } +// ClearAsn clears the value of the "asn" field. +func (ulhuo *UserLoginHistoryUpdateOne) ClearAsn() *UserLoginHistoryUpdateOne { + ulhuo.mutation.ClearAsn() + return ulhuo +} + // SetClientVersion sets the "client_version" field. func (ulhuo *UserLoginHistoryUpdateOne) SetClientVersion(s string) *UserLoginHistoryUpdateOne { ulhuo.mutation.SetClientVersion(s) @@ -436,20 +546,72 @@ func (ulhuo *UserLoginHistoryUpdateOne) SetNillableClientVersion(s *string) *Use return ulhuo } -// SetDevice sets the "device" field. -func (ulhuo *UserLoginHistoryUpdateOne) SetDevice(s string) *UserLoginHistoryUpdateOne { - ulhuo.mutation.SetDevice(s) +// ClearClientVersion clears the value of the "client_version" field. +func (ulhuo *UserLoginHistoryUpdateOne) ClearClientVersion() *UserLoginHistoryUpdateOne { + ulhuo.mutation.ClearClientVersion() return ulhuo } -// SetNillableDevice sets the "device" field if the given value is not nil. -func (ulhuo *UserLoginHistoryUpdateOne) SetNillableDevice(s *string) *UserLoginHistoryUpdateOne { - if s != nil { - ulhuo.SetDevice(*s) +// SetOsType sets the "os_type" field. +func (ulhuo *UserLoginHistoryUpdateOne) SetOsType(ct consts.OSType) *UserLoginHistoryUpdateOne { + ulhuo.mutation.SetOsType(ct) + return ulhuo +} + +// SetNillableOsType sets the "os_type" field if the given value is not nil. +func (ulhuo *UserLoginHistoryUpdateOne) SetNillableOsType(ct *consts.OSType) *UserLoginHistoryUpdateOne { + if ct != nil { + ulhuo.SetOsType(*ct) } return ulhuo } +// ClearOsType clears the value of the "os_type" field. +func (ulhuo *UserLoginHistoryUpdateOne) ClearOsType() *UserLoginHistoryUpdateOne { + ulhuo.mutation.ClearOsType() + return ulhuo +} + +// SetOsRelease sets the "os_release" field. +func (ulhuo *UserLoginHistoryUpdateOne) SetOsRelease(cr consts.OSRelease) *UserLoginHistoryUpdateOne { + ulhuo.mutation.SetOsRelease(cr) + return ulhuo +} + +// SetNillableOsRelease sets the "os_release" field if the given value is not nil. +func (ulhuo *UserLoginHistoryUpdateOne) SetNillableOsRelease(cr *consts.OSRelease) *UserLoginHistoryUpdateOne { + if cr != nil { + ulhuo.SetOsRelease(*cr) + } + return ulhuo +} + +// ClearOsRelease clears the value of the "os_release" field. +func (ulhuo *UserLoginHistoryUpdateOne) ClearOsRelease() *UserLoginHistoryUpdateOne { + ulhuo.mutation.ClearOsRelease() + return ulhuo +} + +// SetHostname sets the "hostname" field. +func (ulhuo *UserLoginHistoryUpdateOne) SetHostname(s string) *UserLoginHistoryUpdateOne { + ulhuo.mutation.SetHostname(s) + return ulhuo +} + +// SetNillableHostname sets the "hostname" field if the given value is not nil. +func (ulhuo *UserLoginHistoryUpdateOne) SetNillableHostname(s *string) *UserLoginHistoryUpdateOne { + if s != nil { + ulhuo.SetHostname(*s) + } + return ulhuo +} + +// ClearHostname clears the value of the "hostname" field. +func (ulhuo *UserLoginHistoryUpdateOne) ClearHostname() *UserLoginHistoryUpdateOne { + ulhuo.mutation.ClearHostname() + return ulhuo +} + // SetCreatedAt sets the "created_at" field. func (ulhuo *UserLoginHistoryUpdateOne) SetCreatedAt(t time.Time) *UserLoginHistoryUpdateOne { ulhuo.mutation.SetCreatedAt(t) @@ -566,9 +728,6 @@ func (ulhuo *UserLoginHistoryUpdateOne) sqlSave(ctx context.Context) (_node *Use } } } - if value, ok := ulhuo.mutation.UserID(); ok { - _spec.SetField(userloginhistory.FieldUserID, field.TypeUUID, value) - } if value, ok := ulhuo.mutation.IP(); ok { _spec.SetField(userloginhistory.FieldIP, field.TypeString, value) } @@ -584,14 +743,38 @@ func (ulhuo *UserLoginHistoryUpdateOne) sqlSave(ctx context.Context) (_node *Use if value, ok := ulhuo.mutation.Isp(); ok { _spec.SetField(userloginhistory.FieldIsp, field.TypeString, value) } + if ulhuo.mutation.IspCleared() { + _spec.ClearField(userloginhistory.FieldIsp, field.TypeString) + } if value, ok := ulhuo.mutation.Asn(); ok { _spec.SetField(userloginhistory.FieldAsn, field.TypeString, value) } + if ulhuo.mutation.AsnCleared() { + _spec.ClearField(userloginhistory.FieldAsn, field.TypeString) + } if value, ok := ulhuo.mutation.ClientVersion(); ok { _spec.SetField(userloginhistory.FieldClientVersion, field.TypeString, value) } - if value, ok := ulhuo.mutation.Device(); ok { - _spec.SetField(userloginhistory.FieldDevice, field.TypeString, value) + if ulhuo.mutation.ClientVersionCleared() { + _spec.ClearField(userloginhistory.FieldClientVersion, field.TypeString) + } + if value, ok := ulhuo.mutation.OsType(); ok { + _spec.SetField(userloginhistory.FieldOsType, field.TypeString, value) + } + if ulhuo.mutation.OsTypeCleared() { + _spec.ClearField(userloginhistory.FieldOsType, field.TypeString) + } + if value, ok := ulhuo.mutation.OsRelease(); ok { + _spec.SetField(userloginhistory.FieldOsRelease, field.TypeString, value) + } + if ulhuo.mutation.OsReleaseCleared() { + _spec.ClearField(userloginhistory.FieldOsRelease, field.TypeString) + } + if value, ok := ulhuo.mutation.Hostname(); ok { + _spec.SetField(userloginhistory.FieldHostname, field.TypeString, value) + } + if ulhuo.mutation.HostnameCleared() { + _spec.ClearField(userloginhistory.FieldHostname, field.TypeString) } if value, ok := ulhuo.mutation.CreatedAt(); ok { _spec.SetField(userloginhistory.FieldCreatedAt, field.TypeTime, value) diff --git a/backend/domain/ip.go b/backend/domain/ip.go new file mode 100644 index 0000000..fe7bac6 --- /dev/null +++ b/backend/domain/ip.go @@ -0,0 +1,8 @@ +package domain + +type IPAddress struct { + IP string `json:"ip"` + Country string `json:"country"` + Province string `json:"province"` + City string `json:"city"` +} diff --git a/backend/domain/oauth.go b/backend/domain/oauth.go index eefba5b..91df152 100644 --- a/backend/domain/oauth.go +++ b/backend/domain/oauth.go @@ -48,6 +48,7 @@ func (o OAuthSignUpOrInReq) OAuthKind() consts.OAuthKind { type OAuthCallbackReq struct { State string `json:"state" query:"state" validate:"required"` Code string `json:"code" query:"code" validate:"required"` + IP string `json:"-"` } type OAuthURLResp struct { diff --git a/backend/domain/user.go b/backend/domain/user.go index 2d5a100..9fa2806 100644 --- a/backend/domain/user.go +++ b/backend/domain/user.go @@ -2,6 +2,7 @@ package domain import ( "context" + "fmt" "github.com/GoYoko/web" @@ -53,6 +54,8 @@ type UserRepo interface { OAuthRegister(ctx context.Context, platform consts.UserPlatform, inviteCode string, req *OAuthUserInfo) (*db.User, error) OAuthLogin(ctx context.Context, platform consts.UserPlatform, req *OAuthUserInfo) (*db.User, error) SignUpOrIn(ctx context.Context, platform consts.UserPlatform, req *OAuthUserInfo) (*db.User, error) + SaveAdminLoginHistory(ctx context.Context, adminID, ip string) error + SaveUserLoginHistory(ctx context.Context, userID, ip string, session *VSCodeSession) error } type UpdateUserReq struct { @@ -67,9 +70,13 @@ type CreateAdminReq struct { } type VSCodeAuthInitReq struct { - ClientID string `json:"client_id" validate:"required"` // 客户端ID - RedirectURI string `json:"redirect_uri" validate:"required"` // 重定向URI - State string `json:"state" validate:"required"` // 状态 + ClientID string `json:"client_id" validate:"required"` // 客户端ID + RedirectURI string `json:"redirect_uri" validate:"required"` // 重定向URI + State string `json:"state" validate:"required"` // 状态 + Version string `json:"version"` // 版本 + OSType consts.OSType `json:"os_type"` // 操作系统类型 + OSRelease consts.OSRelease `json:"os_release"` // 操作系统版本 + Hostname string `json:"hostname"` // 主机名 } type VSCodeAuthInitResp struct { @@ -80,6 +87,7 @@ type LoginReq struct { SessionID string `json:"session_id"` // 会话Id Username string `json:"username"` // 用户名 Password string `json:"password"` // 密码 + IP string `json:"-"` // IP地址 } type AdminLoginReq struct { @@ -152,7 +160,10 @@ func (l *UserLoginHistory) From(e *db.UserLoginHistory) *UserLoginHistory { ASN: e.Asn, } l.ClientVersion = e.ClientVersion - l.Device = e.Device + l.Device = e.OsType.Name() + if e.Hostname != "" { + l.Device += fmt.Sprintf(" (%s)", e.Hostname) + } l.CreatedAt = e.CreatedAt.Unix() return l @@ -248,9 +259,13 @@ func (a *AdminUser) From(e *db.Admin) *AdminUser { } type VSCodeSession struct { - ID string `json:"id"` // 会话ID - State string `json:"state"` // 状态 - RedirectURI string `json:"redirect_uri"` // 重定向URI + ID string `json:"id"` // 会话ID + State string `json:"state"` // 状态 + RedirectURI string `json:"redirect_uri"` // 重定向URI + Version string `json:"version"` // 版本 + OSType consts.OSType `json:"os_type"` // 操作系统类型 + OSRelease consts.OSRelease `json:"os_release"` // 操作系统版本 + Hostname string `json:"hostname"` // 主机名 } type UpdateSettingReq struct { diff --git a/backend/ent/schema/adminloginhistory.go b/backend/ent/schema/adminloginhistory.go index 2c424cb..eb4bb8a 100644 --- a/backend/ent/schema/adminloginhistory.go +++ b/backend/ent/schema/adminloginhistory.go @@ -28,15 +28,15 @@ func (AdminLoginHistory) Annotations() []schema.Annotation { func (AdminLoginHistory) Fields() []ent.Field { return []ent.Field{ field.UUID("id", uuid.UUID{}), - field.UUID("admin_id", uuid.UUID{}), + field.UUID("admin_id", uuid.UUID{}).Optional(), field.String("ip"), field.String("country"), field.String("province"), field.String("city"), - field.String("isp"), - field.String("asn"), - field.String("client_version"), - field.String("device"), + field.String("isp").Optional(), + field.String("asn").Optional(), + field.String("client_version").Optional(), + field.String("device").Optional(), field.Time("created_at").Default(time.Now), } } @@ -44,6 +44,6 @@ func (AdminLoginHistory) Fields() []ent.Field { // Edges of the AdminLoginHistory. func (AdminLoginHistory) Edges() []ent.Edge { return []ent.Edge{ - edge.From("owner", Admin.Type).Ref("login_histories").Unique(), + edge.From("owner", Admin.Type).Field("admin_id").Ref("login_histories").Unique(), } } diff --git a/backend/ent/schema/userloginhistory.go b/backend/ent/schema/userloginhistory.go index f05fa00..c4bcf25 100644 --- a/backend/ent/schema/userloginhistory.go +++ b/backend/ent/schema/userloginhistory.go @@ -9,6 +9,8 @@ import ( "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" "github.com/google/uuid" + + "github.com/chaitin/MonkeyCode/backend/consts" ) // UserLoginHistory holds the schema definition for the UserLoginHistory entity. @@ -28,15 +30,17 @@ func (UserLoginHistory) Annotations() []schema.Annotation { func (UserLoginHistory) Fields() []ent.Field { return []ent.Field{ field.UUID("id", uuid.UUID{}), - field.UUID("user_id", uuid.UUID{}), + field.UUID("user_id", uuid.UUID{}).Optional(), field.String("ip"), field.String("country"), field.String("province"), field.String("city"), - field.String("isp"), - field.String("asn"), - field.String("client_version"), - field.String("device"), + field.String("isp").Optional(), + field.String("asn").Optional(), + field.String("client_version").Optional(), + field.String("os_type").GoType(consts.OSType("")).Optional(), + field.String("os_release").GoType(consts.OSRelease("")).Optional(), + field.String("hostname").Optional(), field.Time("created_at").Default(time.Now), } } @@ -44,6 +48,6 @@ func (UserLoginHistory) Fields() []ent.Field { // Edges of the UserLoginHistory. func (UserLoginHistory) Edges() []ent.Edge { return []ent.Edge{ - edge.From("owner", User.Type).Ref("login_histories").Unique(), + edge.From("owner", User.Type).Field("user_id").Ref("login_histories").Unique(), } } diff --git a/backend/go.mod b/backend/go.mod index bec77b1..e11226b 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -12,6 +12,7 @@ require ( github.com/google/wire v0.6.0 github.com/labstack/echo/v4 v4.13.4 github.com/lib/pq v1.10.9 + github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250630080345-f9402614f6ba github.com/patrickmn/go-cache v2.1.0+incompatible github.com/redis/go-redis/v9 v9.7.3 github.com/rokku-c/go-openai v1.35.7-fix2 diff --git a/backend/go.sum b/backend/go.sum index df38f4f..4b55356 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -163,6 +163,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250630080345-f9402614f6ba h1:t6xeYtXFnvu+GsvgEYyAK5zFnJARSG1fyGzBRZzuOhA= +github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20250630080345-f9402614f6ba/go.mod h1:C5LA5UO2ZXJrLaPLYtE1wUJMiyd/nwWaCO5cw/2pSHs= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= diff --git a/backend/internal/user/handler/v1/user.go b/backend/internal/user/handler/v1/user.go index aef1a72..7292ace 100644 --- a/backend/internal/user/handler/v1/user.go +++ b/backend/internal/user/handler/v1/user.go @@ -203,6 +203,7 @@ func (h *UserHandler) VSIXDownload(c *web.Context) error { // @Success 200 {object} web.Resp{data=domain.LoginResp} // @Router /api/v1/user/login [post] func (h *UserHandler) Login(c *web.Context, req domain.LoginReq) error { + req.IP = c.RealIP() resp, err := h.usecase.Login(c.Request().Context(), &req) if err != nil { return err @@ -279,6 +280,7 @@ func (h *UserHandler) DeleteAdmin(c *web.Context) error { // @Success 200 {object} web.Resp{data=domain.AdminUser} // @Router /api/v1/admin/login [post] func (h *UserHandler) AdminLogin(c *web.Context, req domain.LoginReq) error { + req.IP = c.RealIP() resp, err := h.usecase.AdminLogin(c.Request().Context(), &req) if err != nil { return err @@ -497,6 +499,7 @@ func (h *UserHandler) OAuthSignUpOrIn(ctx *web.Context, req domain.OAuthSignUpOr // @Success 200 {object} web.Resp{data=string} // @Router /api/v1/user/oauth/callback [get] func (h *UserHandler) OAuthCallback(ctx *web.Context, req domain.OAuthCallbackReq) error { + req.IP = ctx.RealIP() resp, err := h.usecase.OAuthCallback(ctx.Request().Context(), &req) if err != nil { return err diff --git a/backend/internal/user/repo/user.go b/backend/internal/user/repo/user.go index 02ca683..108ec56 100644 --- a/backend/internal/user/repo/user.go +++ b/backend/internal/user/repo/user.go @@ -6,6 +6,7 @@ import ( "fmt" "time" + "entgo.io/ent/dialect/sql" "github.com/google/uuid" "github.com/GoYoko/web" @@ -13,21 +14,25 @@ import ( "github.com/chaitin/MonkeyCode/backend/consts" "github.com/chaitin/MonkeyCode/backend/db" "github.com/chaitin/MonkeyCode/backend/db/admin" + "github.com/chaitin/MonkeyCode/backend/db/adminloginhistory" "github.com/chaitin/MonkeyCode/backend/db/apikey" "github.com/chaitin/MonkeyCode/backend/db/invitecode" "github.com/chaitin/MonkeyCode/backend/db/user" "github.com/chaitin/MonkeyCode/backend/db/useridentity" + "github.com/chaitin/MonkeyCode/backend/db/userloginhistory" "github.com/chaitin/MonkeyCode/backend/domain" "github.com/chaitin/MonkeyCode/backend/errcode" "github.com/chaitin/MonkeyCode/backend/pkg/entx" + "github.com/chaitin/MonkeyCode/backend/pkg/ipdb" ) type UserRepo struct { - db *db.Client + db *db.Client + ipdb *ipdb.IPDB } -func NewUserRepo(db *db.Client) domain.UserRepo { - return &UserRepo{db: db} +func NewUserRepo(db *db.Client, ipdb *ipdb.IPDB) domain.UserRepo { + return &UserRepo{db: db, ipdb: ipdb} } func (r *UserRepo) InitAdmin(ctx context.Context, username, password string) error { @@ -115,12 +120,12 @@ func (r *UserRepo) CreateUser(ctx context.Context, user *db.User) (*db.User, err } func (r *UserRepo) UserLoginHistory(ctx context.Context, page *web.Pagination) ([]*db.UserLoginHistory, *db.PageInfo, error) { - q := r.db.UserLoginHistory.Query() + q := r.db.UserLoginHistory.Query().WithOwner().Order(userloginhistory.ByCreatedAt(sql.OrderDesc())) return q.Page(ctx, page.Page, page.Size) } func (r *UserRepo) AdminLoginHistory(ctx context.Context, page *web.Pagination) ([]*db.AdminLoginHistory, *db.PageInfo, error) { - q := r.db.AdminLoginHistory.Query() + q := r.db.AdminLoginHistory.Query().WithOwner().Order(adminloginhistory.ByCreatedAt(sql.OrderDesc())) return q.Page(ctx, page.Page, page.Size) } @@ -369,3 +374,45 @@ func (r *UserRepo) SignUpOrIn(ctx context.Context, platform consts.UserPlatform, }) return u, err } + +func (r *UserRepo) SaveAdminLoginHistory(ctx context.Context, adminID string, ip string) error { + uid, err := uuid.Parse(adminID) + if err != nil { + return err + } + addr, err := r.ipdb.Lookup(ip) + if err != nil { + return err + } + _, err = r.db.AdminLoginHistory.Create(). + SetAdminID(uid). + SetIP(ip). + SetCity(addr.City). + SetCountry(addr.Country). + SetProvince(addr.Province). + Save(ctx) + return err +} + +func (r *UserRepo) SaveUserLoginHistory(ctx context.Context, userID string, ip string, session *domain.VSCodeSession) error { + uid, err := uuid.Parse(userID) + if err != nil { + return err + } + addr, err := r.ipdb.Lookup(ip) + if err != nil { + return err + } + _, err = r.db.UserLoginHistory.Create(). + SetUserID(uid). + SetIP(ip). + SetCity(addr.City). + SetCountry(addr.Country). + SetProvince(addr.Province). + SetClientVersion(session.Version). + SetOsType(session.OSType). + SetOsRelease(session.OSRelease). + SetHostname(session.Hostname). + Save(ctx) + return err +} diff --git a/backend/internal/user/usecase/user.go b/backend/internal/user/usecase/user.go index 0931333..77b79dc 100644 --- a/backend/internal/user/usecase/user.go +++ b/backend/internal/user/usecase/user.go @@ -116,7 +116,7 @@ func (u *UserUsecase) AdminLoginHistory(ctx context.Context, page *web.Paginatio return &domain.ListAdminLoginHistoryResp{ PageInfo: p, LoginHistories: cvt.Iter(histories, func(_ int, e *db.AdminLoginHistory) *domain.AdminLoginHistory { - return cvt.From(e, &domain.AdminLoginHistory{}).From(e) + return cvt.From(e, &domain.AdminLoginHistory{}) }), }, nil } @@ -187,26 +187,30 @@ func (u *UserUsecase) Login(ctx context.Context, req *domain.LoginReq) (*domain. return nil, err } - r, err := u.getVSCodeURL(ctx, req.SessionID, apiKey.Key, user.Username) + r, session, err := u.getVSCodeURL(ctx, req.SessionID, apiKey.Key, user.Username) if err != nil { return nil, err } + + if err := u.repo.SaveUserLoginHistory(ctx, user.ID.String(), req.IP, session); err != nil { + u.logger.With("error", err).Error("save user login history") + } return &domain.LoginResp{ RedirectURL: r, }, nil } -func (u *UserUsecase) getVSCodeURL(ctx context.Context, sessionID, apiKey, username string) (string, error) { +func (u *UserUsecase) getVSCodeURL(ctx context.Context, sessionID, apiKey, username string) (string, *domain.VSCodeSession, error) { s, err := u.redis.Get(ctx, fmt.Sprintf("vscode:session:%s", sessionID)).Result() if err != nil { - return "", err + return "", nil, err } session := &domain.VSCodeSession{} if err := json.Unmarshal([]byte(s), session); err != nil { - return "", err + return "", nil, err } r := fmt.Sprintf("%s?state=%s&api_key=%s&expires_in=3600&username=%s", session.RedirectURI, session.State, apiKey, username) - return r, nil + return r, session, nil } func (u *UserUsecase) AdminLogin(ctx context.Context, req *domain.LoginReq) (*domain.AdminUser, error) { @@ -217,6 +221,10 @@ func (u *UserUsecase) AdminLogin(ctx context.Context, req *domain.LoginReq) (*do if err := bcrypt.CompareHashAndPassword([]byte(admin.Password), []byte(req.Password)); err != nil { return nil, errcode.ErrPassword.Wrap(err) } + + if err := u.repo.SaveAdminLoginHistory(ctx, admin.ID.String(), req.IP); err != nil { + return nil, err + } return cvt.From(admin, &domain.AdminUser{}), nil } @@ -226,6 +234,10 @@ func (u *UserUsecase) VSCodeAuthInit(ctx context.Context, req *domain.VSCodeAuth ID: i, State: req.State, RedirectURI: req.RedirectURI, + Version: req.Version, + OSType: req.OSType, + OSRelease: req.OSRelease, + Hostname: req.Hostname, } b, err := json.Marshal(session) @@ -513,11 +525,14 @@ func (u *UserUsecase) WithOAuthCallback(ctx context.Context, req *domain.OAuthCa redirect := session.RedirectURL if session.SessionID != "" { - r, err := u.getVSCodeURL(ctx, session.SessionID, apiKey.Key, user.Username) + r, vsess, err := u.getVSCodeURL(ctx, session.SessionID, apiKey.Key, user.Username) if err != nil { return "", err } redirect = fmt.Sprintf("%s?redirect_url=%s", redirect, url.QueryEscape(r)) + if err := u.repo.SaveUserLoginHistory(ctx, user.ID.String(), req.IP, vsess); err != nil { + u.logger.With("error", err).Error("save user login history") + } } u.logger.Debug("oauth callback", "redirect", redirect) diff --git a/backend/migration/000008_alter_user_login_histories_table.down.sql b/backend/migration/000008_alter_user_login_histories_table.down.sql new file mode 100644 index 0000000..e69de29 diff --git a/backend/migration/000008_alter_user_login_histories_table.up.sql b/backend/migration/000008_alter_user_login_histories_table.up.sql new file mode 100644 index 0000000..dbf4237 --- /dev/null +++ b/backend/migration/000008_alter_user_login_histories_table.up.sql @@ -0,0 +1,5 @@ +ALTER TABLE user_login_histories DROP COLUMN IF EXISTS device; + +ALTER TABLE user_login_histories ADD COLUMN IF NOT EXISTS hostname VARCHAR(255); +ALTER TABLE user_login_histories ADD COLUMN IF NOT EXISTS os_type VARCHAR(255); +ALTER TABLE user_login_histories ADD COLUMN IF NOT EXISTS os_release VARCHAR(255); diff --git a/backend/pkg/ipdb/ip2region.xdb b/backend/pkg/ipdb/ip2region.xdb new file mode 100644 index 0000000..c68c177 --- /dev/null +++ b/backend/pkg/ipdb/ip2region.xdb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:867b619b567f51bb9dd3c384a4cbf7c33e71a178aa58f13201499aadaf2cf78e +size 11070083 diff --git a/backend/pkg/ipdb/ipdb.go b/backend/pkg/ipdb/ipdb.go new file mode 100644 index 0000000..d0cb30d --- /dev/null +++ b/backend/pkg/ipdb/ipdb.go @@ -0,0 +1,61 @@ +package ipdb + +import ( + "embed" + "fmt" + "log/slog" + "strings" + + "github.com/lionsoul2014/ip2region/binding/golang/xdb" + + "github.com/chaitin/MonkeyCode/backend/domain" +) + +//go:embed ip2region.xdb +var ipdbFiles embed.FS + +type IPDB struct { + searcher *xdb.Searcher + logger *slog.Logger +} + +func NewIPDB(logger *slog.Logger) (*IPDB, error) { + cBuff, err := xdb.LoadContentFromFS(ipdbFiles, "ip2region.xdb") + if err != nil { + return nil, fmt.Errorf("load xdb index failed: %w", err) + } + searcher, err := xdb.NewWithBuffer(cBuff) + if err != nil { + return nil, fmt.Errorf("new xdb reader failed: %w", err) + } + return &IPDB{searcher: searcher, logger: logger.With("module", "ipdb")}, nil +} + +func (a *IPDB) Lookup(ip string) (*domain.IPAddress, error) { + region, err := a.searcher.SearchByStr(ip) + if err != nil { + return nil, fmt.Errorf("search ip failed: %w", err) + } + ipInfo := strings.Split(region, "|") + if len(ipInfo) != 5 { + return nil, fmt.Errorf("invalid ip info: %s", region) + } + country := ipInfo[0] + province := ipInfo[2] + city := ipInfo[3] + if country == "0" { + country = "未知" + } + if province == "0" { + province = "未知" + } + if city == "0" { + city = "未知" + } + return &domain.IPAddress{ + IP: ip, + Country: country, + Province: province, + City: city, + }, nil +} diff --git a/backend/pkg/provider.go b/backend/pkg/provider.go index 0da99a1..744396c 100644 --- a/backend/pkg/provider.go +++ b/backend/pkg/provider.go @@ -11,6 +11,7 @@ import ( "github.com/chaitin/MonkeyCode/backend/config" "github.com/chaitin/MonkeyCode/backend/errcode" mid "github.com/chaitin/MonkeyCode/backend/internal/middleware" + "github.com/chaitin/MonkeyCode/backend/pkg/ipdb" "github.com/chaitin/MonkeyCode/backend/pkg/logger" "github.com/chaitin/MonkeyCode/backend/pkg/session" "github.com/chaitin/MonkeyCode/backend/pkg/store" @@ -22,6 +23,7 @@ var Provider = wire.NewSet( store.NewEntDB, store.NewRedisCli, session.NewSession, + ipdb.NewIPDB, ) func NewWeb(cfg *config.Config) *web.Web {