Documentation ¶
Index ¶
- type APIKey
- type APIKeyChanges
- type APIKeyConflicts
- type ActiveSession
- type AuthClaims
- type Billing
- func (b *Billing) HasCurrentPeriodEnd() bool
- func (b *Billing) HasCutomer() bool
- func (b *Billing) HasSubscription() bool
- func (b *Billing) IsActive() bool
- func (b *Billing) IsNil() bool
- func (b *Billing) SetCurrentPeriodEnd(end int64)
- func (b *Billing) SetCustomer(id string)
- func (b *Billing) SetSubscription(id string, status BillingStatus)
- func (b *Billing) UpdateBillingStatus(status BillingStatus)
- type BillingEvaluation
- type BillingStatus
- type ConnectedDevice
- type Device
- type DeviceAuth
- type DeviceAuthClaims
- type DeviceAuthRequest
- type DeviceAuthResponse
- type DeviceIdentity
- type DeviceInfo
- type DevicePosition
- type DeviceRemoved
- type DeviceStatus
- type DeviceTag
- type Endpoints
- type Filter
- type FirewallFilter
- type FirewallRule
- type FirewallRuleFields
- type FirewallRuleUpdate
- type ID
- type Info
- type Member
- type MemberChanges
- type Namespace
- type NamespaceChanges
- type NamespaceSettings
- type OperatorParams
- type PrivateKey
- type PropertyParams
- type PublicKey
- type PublicKeyAuthRequest
- type PublicKeyAuthResponse
- type PublicKeyFields
- type PublicKeyFilter
- type PublicKeyUpdate
- type RecordedSession
- type Session
- type SessionPosition
- type SessionRecorded
- type SessionUpdate
- type Stats
- type Status
- type SystemInfo
- type SystemInfoEndpoints
- type Tenant
- type UID
- type User
- type UserAuthClaims
- type UserAuthIdentifier
- type UserAuthResponse
- type UserChanges
- type UserConflicts
- type UserData
- type UserMFA
- type UserPassword
- type UserPreferences
- type UserTokenRecover
- type Username
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIKey ¶ added in v0.15.0
type APIKey struct { // ID is the unique identifier of the API key. It is a SHA256 hash of a UUID. ID string `json:"-" bson:"_id"` // Name is an external identifier for a given API key. It is not unique per document but // is unique per tenant ID. Name string `json:"name" bson:"name"` // TenantID is the API key's namespace ID. TenantID string `json:"tenant_id" bson:"tenant_id"` // Role defines the permissions of the API key. It must be equal to or less than the creator's role. Role authorizer.Role `json:"role" bson:"role" validate:"required,oneof=administrator operator observer"` // CreatedBy is the ID of the user who created the API key. CreatedBy string `json:"created_by" bson:"created_by"` // CreatedAt is the creation date of the API key. CreatedAt time.Time `json:"created_at" bson:"created_at"` // UpdatedAt is the last update date of the API key. UpdatedAt time.Time `json:"updated_at" bson:"updated_at"` // ExpiresIn is the expiration date of the API key. An expired key cannot be used for // authentication. When equals or less than 0 it means that are no expiration date. ExpiresIn int64 `json:"expires_in" bson:"expires_in"` }
APIKey is used to authenticate a request. It is similar to UserAuthClaims but only for namespace information, which means that user-related routes are blocked for use with api keys. The ID and key are never returned to the end user; the "external" identification must be made by name and tenant only.
Expired keys cannot be used for authentication. Use APIKey.IsValid to verify its validity.
type APIKeyChanges ¶ added in v0.16.0
type APIKeyChanges struct { UpdatedAt time.Time `bson:"updated_at,omitempty"` Name string `bson:"name,omitempty"` Role authorizer.Role `bson:"role,omitempty"` }
APIKeyChanges specifies the attributes that can be updated for an API key. Any zero values in this struct must be ignored. If an attribute is a pointer type, its zero value is represented as `nil`.
type APIKeyConflicts ¶ added in v0.16.0
APIKeyConflicts holds API keys attributes that must be unique for each item (per tenant ID) and can be utilized in queries to identify conflicts.
type ActiveSession ¶
type AuthClaims ¶ added in v0.2.0
type AuthClaims struct {
Claims string `json:"claims"`
}
type Billing ¶ added in v0.8.0
type Billing struct { // Active indicates if the subscription is active. // IT IS THE SOURCE OF TRUTH THAT DEFINES WHETHER A SUBSCRIPTION IS ACTIVE OR NOT and change due to the status of // the subscription. // // A subscription is active if its status is `active`, `trailing`, `past_due` or `to_cancel_at_end_of_period`. // `past_due` is a temporary status that occurs when a payment to renew the subscription fails, but the subscription // has not been canceled yet. // `to_cancel_at_end_of_period` is a custom status used by this package to indicate that the subscription is set to // cancel at the end of the period. // A subscription is not active if its status is `incomplete`, `incomplete_expired`, `canceled`, `unpaid` or `paused`. // TODO: evaluate if `paused` should be considered active. Active bool `json:"active" bson:"active"` // Status is the current status of the subscription. Status BillingStatus `json:"status" bson:"status"` // Customer is the ID of the customer the subscription belongs to. // Customer string `json:"customer" bson:"customer"` CustomerID string `json:"customer_id" bson:"customer_id"` // SubscriptionID is the ID of the subscription. SubscriptionID string `json:"subscription_id" bson:"subscription_id"` // CurrentPeriodEnd is the end of the current period. CurrentPeriodEnd int64 `json:"current_period_end" bson:"current_period_end"` // CreatedAt is the time at which this billing was created. // It must follow the RFC 3339 format. CreatedAt string `json:"created_at" bson:"created_at"` // UpdatedAt is the time at which this billing was last updated. // It must follow the RFC 3339 format. UpdatedAt string `json:"updated_at" bson:"updated_at"` }
Billing contains information about the ShellHub's subscription.
func NewBilling ¶ added in v0.12.4
func NewBilling(status BillingStatus, customer, subscription string, currentPeridoEnd int64) *Billing
func (*Billing) HasCurrentPeriodEnd ¶ added in v0.12.4
func (*Billing) HasCutomer ¶ added in v0.12.4
func (*Billing) HasSubscription ¶ added in v0.12.4
func (*Billing) SetCurrentPeriodEnd ¶ added in v0.12.4
func (*Billing) SetCustomer ¶ added in v0.12.4
func (*Billing) SetSubscription ¶ added in v0.12.4
func (b *Billing) SetSubscription(id string, status BillingStatus)
func (*Billing) UpdateBillingStatus ¶ added in v0.12.4
func (b *Billing) UpdateBillingStatus(status BillingStatus)
UpdateBillingStatus updates the status of the billing.
type BillingEvaluation ¶ added in v0.12.4
type BillingEvaluation struct { // CanAccept indicates if the namespace can accept a new device. CanAccept bool `json:"can_accept"` // CanConnect indicates if the namespace can create a new connection SSH. CanConnect bool `json:"can_connect"` }
BillingEvaluation contains information about the billing evaluation of acceptance and connection. It is used to evaluate if a device can be accepted or a connection SSH can be created. Its idea is simplify the check the state of the namespace when related to billing.
type BillingStatus ¶ added in v0.12.4
type BillingStatus string
BillingStatus represents the status of a subscription.
https://stripe.com/docs/api/subscriptions/object#subscription_object-status https://stripe.com/docs/billing/subscriptions/overview#subscription-lifecycle
const ( // BillingStatusInactive represents inactive status. BillingStatusInactive BillingStatus = "inactive" // BillingStatusActive represents active status without any issues. BillingStatusActive BillingStatus = "active" // BillingStatusTrialing represents active status without any issues, but the subscription is in trial period. BillingStatusTrialing BillingStatus = "trialing" // BillingStatusIncomplete represents incomplete status. // If the initial payment attempt fails, the status of the subscription becomes incomplete. // If payment fails because of a card error, such as a decline, the status of the PaymentIntent is // requires_card and the subscription is incomplete. BillingStatusIncomplete BillingStatus = "incomplete" // BillingStatusIncompleteExpired represents incomplete_expired status. // If the first invoice is not paid within 23 hours, the status of the subscription becomes incomplete_expired. BillingStatusIncompleteExpired BillingStatus = "incomplete_expired" // BillingStatusPastDue represents past_due status. // The subscription’s status remains active as long as automatic payments succeed. If automatic payment fails, the // subscription updates to past_due and Stripe attempts to recover payment based on your retry rules. If payment // recovery fails, you can set the subscription status to canceled, unpaid, or leave it past_due. BillingStatusPastDue BillingStatus = "past_due" // BillingStatusCanceled represents canceled status. BillingStatusCanceled BillingStatus = "canceled" // BillingStatusUnpaid represents unpaid status. // If the retry attempts are exhausted, the status of the subscription becomes unpaid, depending on your subscriptions settings. BillingStatusUnpaid BillingStatus = "unpaid" // BillingStatusPaused represents paused status. BillingStatusPaused BillingStatus = "paused" // BillingStatusToCancelAtEndOfPeriod represents to_cancel_at_end_of_period status. // BillingStatusToCancelAtEndOfPeriod is not a Stripe status, but a custom status used by this package to indicate that the subscription is set to cancel at the end of the period. BillingStatusToCancelAtEndOfPeriod BillingStatus = "to_cancel_at_end_of_period" )
Represents the possible statuses of a subscription.
func (BillingStatus) IsActive ¶ added in v0.12.4
func (s BillingStatus) IsActive() bool
IsActive returns true if the subscription is active. It is active if its status is `active`, `past_due`, `trailing` or `to_cancel_at_end_of_period`.
type ConnectedDevice ¶
type Device ¶
type Device struct { // UID is the unique identifier for a device. UID string `json:"uid"` Name string `json:"name" bson:"name,omitempty" validate:"required,device_name"` Identity *DeviceIdentity `json:"identity"` Info *DeviceInfo `json:"info"` PublicKey string `json:"public_key" bson:"public_key"` TenantID string `json:"tenant_id" bson:"tenant_id"` LastSeen time.Time `json:"last_seen" bson:"last_seen"` Online bool `json:"online" bson:",omitempty"` Namespace string `json:"namespace" bson:",omitempty"` Status DeviceStatus `json:"status" bson:"status,omitempty" validate:"oneof=accepted rejected pending unused"` StatusUpdatedAt time.Time `json:"status_updated_at" bson:"status_updated_at,omitempty"` CreatedAt time.Time `json:"created_at" bson:"created_at,omitempty"` RemoteAddr string `json:"remote_addr" bson:"remote_addr"` Position *DevicePosition `json:"position" bson:"position"` Tags []string `json:"tags" bson:"tags,omitempty"` PublicURL bool `json:"public_url" bson:"public_url,omitempty"` PublicURLAddress string `json:"public_url_address" bson:"public_url_address,omitempty"` Acceptable bool `json:"acceptable" bson:"acceptable,omitempty"` }
type DeviceAuth ¶
type DeviceAuth struct { Hostname string `json:"hostname,omitempty" bson:"hostname,omitempty" validate:"required_without=Identity,omitempty,hostname_rfc1123" hash:"-"` Identity *DeviceIdentity `json:"identity,omitempty" bson:"identity,omitempty" validate:"required_without=Hostname,omitempty"` PublicKey string `json:"public_key"` TenantID string `json:"tenant_id"` }
type DeviceAuthClaims ¶
type DeviceAuthClaims struct { UID string `json:"uid"` Tenant string `json:"tenant"` AuthClaims `mapstruct:",squash"` jwt.RegisteredClaims `mapstruct:",squash"` }
func (*DeviceAuthClaims) WithDefaults ¶ added in v0.16.0
func (d *DeviceAuthClaims) WithDefaults() *DeviceAuthClaims
WithDefaults fill itself with default JWT attributes. Returns itself.
type DeviceAuthRequest ¶
type DeviceAuthRequest struct { Info *DeviceInfo `json:"info"` Sessions []string `json:"sessions,omitempty"` *DeviceAuth }
type DeviceAuthResponse ¶
type DeviceIdentity ¶ added in v0.2.1
type DeviceIdentity struct {
MAC string `json:"mac"`
}
type DeviceInfo ¶ added in v0.2.1
type DevicePosition ¶ added in v0.8.0
type DeviceRemoved ¶ added in v0.11.8
type DeviceStatus ¶ added in v0.11.8
type DeviceStatus string
const ( DeviceStatusAccepted DeviceStatus = "accepted" DeviceStatusPending DeviceStatus = "pending" DeviceStatusRejected DeviceStatus = "rejected" DeviceStatusRemoved DeviceStatus = "removed" DeviceStatusUnused DeviceStatus = "unused" DeviceStatusEmpty DeviceStatus = "" )
type DeviceTag ¶ added in v0.14.0
type DeviceTag struct {
Tag string `validate:"required,min=3,max=255,alphanum,ascii,excludes=/@&:"`
}
func NewDeviceTag ¶ added in v0.14.0
type Filter ¶ added in v0.3.0
type Filter struct { // Type os the filter. Type can be "property" or "operator". When Type is "property", the Params field must is set // to PropertyParams structure and when set "operator", the Params field must be set to OperatorParams structure. Type string `json:"type,omitempty"` // Params is the filter params. Params can be either PropertyParams or OperatorParams. Params interface{} `json:"params,omitempty"` }
Filter is a helper struct to filter results from the database. TODO: Gives a better explanation about the filter and how to use it.
func (*Filter) UnmarshalJSON ¶ added in v0.3.2
type FirewallFilter ¶ added in v0.9.1
type FirewallFilter struct { Hostname string `json:"hostname,omitempty" bson:"hostname,omitempty" validate:"required_without=Tags,excluded_with=Tags,regexp"` Tags []string `` /* 164-byte string literal not displayed */ }
FirewallFilter contains the filter rule of a Public Key.
A FirewallFilter can contain either Hostname, string, or Tags, slice of strings never both.
type FirewallRule ¶ added in v0.3.3
type FirewallRule struct { ID string `json:"id,omitempty" bson:"_id,omitempty"` TenantID string `json:"tenant_id" bson:"tenant_id"` FirewallRuleFields `bson:",inline"` }
type FirewallRuleFields ¶ added in v0.3.3
type FirewallRuleFields struct { Priority int `json:"priority"` Action string `json:"action" validate:"required,oneof=allow deny"` Active bool `json:"active"` SourceIP string `json:"source_ip" bson:"source_ip" validate:"required,regexp"` Username string `json:"username" validate:"required,regexp"` Filter FirewallFilter `json:"filter" bson:"filter" validate:"required"` }
func (*FirewallRuleFields) Validate ¶ added in v0.3.3
func (f *FirewallRuleFields) Validate() error
type FirewallRuleUpdate ¶ added in v0.3.3
type FirewallRuleUpdate struct {
FirewallRuleFields `bson:",inline"`
}
type Member ¶ added in v0.5.0
type Member struct { ID string `json:"id,omitempty" bson:"id,omitempty"` Username string `json:"username,omitempty" bson:"username,omitempty" validate:"username"` Role authorizer.Role `json:"role" bson:"role" validate:"required,oneof=administrator operator observer"` }
type MemberChanges ¶ added in v0.16.0
type MemberChanges struct {
Role authorizer.Role `bson:"role,omitempty"`
}
type Namespace ¶ added in v0.5.0
type Namespace struct { Name string `json:"name" validate:"required,hostname_rfc1123,excludes=.,lowercase"` Owner string `json:"owner"` TenantID string `json:"tenant_id" bson:"tenant_id,omitempty"` Members []Member `json:"members" bson:"members"` Settings *NamespaceSettings `json:"settings"` Devices int `json:"-" bson:"devices,omitempty"` Sessions int `json:"-" bson:"sessions,omitempty"` MaxDevices int `json:"max_devices" bson:"max_devices"` DevicesCount int `json:"devices_count" bson:"devices_count,omitempty"` CreatedAt time.Time `json:"created_at" bson:"created_at"` Billing *Billing `json:"billing" bson:"billing,omitempty"` }
func (*Namespace) FindMember ¶ added in v0.14.0
FindMember checks if a member with the specified ID exists in the namespace.
func (*Namespace) HasLimitDevicesReached ¶ added in v0.15.0
HasLimitDevicesReached checks if the namespace limit was reached using the removed devices collection.
This method is intended to be run only when the ShellHub instance is Cloud.
func (*Namespace) HasMaxDevices ¶ added in v0.11.8
HasMaxDevices checks if the namespace has a maximum number of devices.
Generally, a namespace has a MaxDevices value greater than 0 when the ShellHub is either in community version or the namespace does not have a billing plan enabled, because, in this case, we set this value to -1.
func (*Namespace) HasMaxDevicesReached ¶ added in v0.11.8
HasMaxDevicesReached checks if the namespace has reached the maximum number of devices.
type NamespaceChanges ¶ added in v0.15.0
type NamespaceSettings ¶ added in v0.5.0
type OperatorParams ¶ added in v0.3.2
type OperatorParams struct {
Name string `json:"name"`
}
type PrivateKey ¶ added in v0.5.0
type PropertyParams ¶ added in v0.3.2
type PublicKeyAuthRequest ¶ added in v0.5.0
type PublicKeyAuthResponse ¶ added in v0.5.0
type PublicKeyAuthResponse struct {
Signature string `json:"signature"`
}
type PublicKeyFields ¶ added in v0.5.0
type PublicKeyFields struct { Name string `json:"name"` Username string `json:"username" bson:"username" validate:"regexp"` Filter PublicKeyFilter `json:"filter" bson:"filter" validate:"required"` }
func (*PublicKeyFields) Validate ¶ added in v0.6.1
func (p *PublicKeyFields) Validate() error
type PublicKeyFilter ¶ added in v0.9.1
type PublicKeyFilter struct { Hostname string `json:"hostname,omitempty" bson:"hostname,omitempty" validate:"required_without=Tags,excluded_with=Tags,regexp"` Tags []string `` /* 164-byte string literal not displayed */ }
PublicKeyFilter contains the filter rule of a Public Key.
A PublicKeyFilter can contain either Hostname, string, or Tags, slice of strings never both.
type PublicKeyUpdate ¶ added in v0.5.0
type PublicKeyUpdate struct {
PublicKeyFields `bson:",inline"`
}
type RecordedSession ¶ added in v0.4.0
type RecordedSession struct { UID UID `json:"uid"` Message string `json:"message" bson:"message"` TenantID string `json:"tenant_id" bson:"tenant_id,omitempty"` Time time.Time `json:"time" bson:"time,omitempty"` Width int `json:"width" bson:"width,omitempty"` Height int `json:"height" bson:"height,omitempty"` }
NOTE: This struct has been moved to the cloud repo as it is only used in a cloud context; however, it is also utilized by migrations. For this reason, we must maintain the struct here ensure everything continues to function as expected. TODO: Remove this struct when it is no longer needed for migrations.
type Session ¶
type Session struct { UID string `json:"uid"` DeviceUID UID `json:"device_uid,omitempty" bson:"device_uid"` Device *Device `json:"device" bson:"-"` TenantID string `json:"tenant_id" bson:"tenant_id"` Username string `json:"username"` IPAddress string `json:"ip_address" bson:"ip_address"` StartedAt time.Time `json:"started_at" bson:"started_at"` LastSeen time.Time `json:"last_seen" bson:"last_seen"` Active bool `json:"active" bson:"active"` Closed bool `json:"-" bson:"closed"` Authenticated bool `json:"authenticated" bson:"authenticated"` Recorded bool `json:"recorded" bson:"recorded"` Type string `json:"type" bson:"type"` Term string `json:"term" bson:"term"` Position SessionPosition `json:"position" bson:"position"` }
type SessionPosition ¶ added in v0.10.0
type SessionRecorded ¶ added in v0.7.3
type SessionUpdate ¶ added in v0.16.0
type SystemInfo ¶ added in v0.11.8
type SystemInfo struct { Version string `json:"version"` Endpoints *SystemInfoEndpoints `json:"endpoints"` }
type SystemInfoEndpoints ¶ added in v0.11.8
type User ¶
type User struct { ID string `json:"id,omitempty" bson:"_id,omitempty"` Namespaces int `json:"namespaces" bson:"namespaces,omitempty"` MaxNamespaces int `json:"max_namespaces" bson:"max_namespaces"` Confirmed bool `json:"confirmed"` CreatedAt time.Time `json:"created_at" bson:"created_at"` LastLogin time.Time `json:"last_login" bson:"last_login"` EmailMarketing bool `json:"email_marketing" bson:"email_marketing"` UserData `bson:",inline"` // MFA contains attributes related to a user's MFA settings. Use [UserMFA.Enabled] to // check if MFA is active for the user. // // NOTE: MFA is available as a cloud-only feature and must be ignored in community. MFA UserMFA `json:"mfa" bson:"mfa"` Preferences UserPreferences `json:"-" bson:"preferences"` Password UserPassword `bson:",inline"` }
type UserAuthClaims ¶
type UserAuthClaims struct { ID string `json:"id"` Tenant string `json:"tenant"` Role authorizer.Role `json:"-"` Username string `json:"name"` MFA bool `json:"mfa"` AuthClaims `mapstruct:",squash"` jwt.RegisteredClaims `mapstruct:",squash"` }
func (*UserAuthClaims) WithDefaults ¶ added in v0.16.0
func (u *UserAuthClaims) WithDefaults() *UserAuthClaims
WithDefaults fill itself with default JWT attributes. Returns itself.
type UserAuthIdentifier ¶ added in v0.14.0
type UserAuthIdentifier string
UserAuthIdentifier is an username or email used to authenticate.
func (*UserAuthIdentifier) IsEmail ¶ added in v0.14.0
func (i *UserAuthIdentifier) IsEmail() bool
IsEmail checks if the identifier is an email.
type UserAuthResponse ¶
type UserChanges ¶ added in v0.16.0
type UserChanges struct { LastLogin time.Time `bson:"last_login,omitempty"` Name string `bson:"name,omitempty"` Username string `bson:"username,omitempty"` Email string `bson:"email,omitempty"` RecoveryEmail string `bson:"recovery_email,omitempty"` Password string `bson:"password,omitempty"` Confirmed *bool `bson:"confirmed,omitempty"` PreferredNamespace *string `bson:"preferences.preferred_namespace,omitempty"` }
UserChanges specifies the attributes that can be updated for a user. Any zero values in this struct must be ignored. If an attribute is a pointer type, its zero value is represented as `nil`.
type UserConflicts ¶ added in v0.16.0
UserConflicts holds user attributes that must be unique for each itam and can be utilized in queries to identify conflicts.
func (*UserConflicts) Distinct ¶ added in v0.16.0
func (c *UserConflicts) Distinct(user *User)
Distinct removes the c attributes whether it's equal to the user attribute.
type UserData ¶ added in v0.8.0
type UserData struct { Name string `json:"name" validate:"required,name"` Username string `json:"username" bson:",omitempty" validate:"required,username"` Email string `json:"email" bson:",omitempty" validate:"required,email"` // RecoveryEmail is a custom, non-unique email address that a user can use to recover their account // when they lose access to all other methods. It must never be equal to [UserData.Email]. // // NOTE: Recovery email is available as a cloud-only feature and must be ignored in community. RecoveryEmail string `json:"recovery_email" bson:"recovery_email" validate:"omitempty,email"` }
type UserMFA ¶ added in v0.16.0
type UserMFA struct { // Enabled reports whether MFA is enabled for the user. Enabled bool `json:"enabled" bson:"enabled"` // Secret is the key used for authenticating with the OTP server. Secret string `json:"-" bson:"secret"` // RecoveryCodes are recovery tokens that the user can use to regain account access if they lose their MFA device. RecoveryCodes []string `json:"-" bson:"recovery_codes"` }
UserMFA represents the attributes related to MFA for a user.
type UserPassword ¶ added in v0.8.0
type UserPassword struct { // Plain contains the plain text password. Plain string `json:"password" bson:"-" validate:"required,password"` // Hash contains the hashed pasword from plain text. Hash string `json:"-" bson:"password"` }
func HashUserPassword ¶ added in v0.15.0
func HashUserPassword(plain string) (UserPassword, error)
HashUserPassword receives a plain password and hash it, returning a UserPassword.
func (*UserPassword) Compare ¶ added in v0.14.0
func (p *UserPassword) Compare(plain string) bool
Compare reports whether a plain password matches with hash.
For compatibility purposes, it can compare using both SHA256 and bcrypt algorithms. Hashes starting with "$" are assumed to be a bcrypt hash; otherwise, they are treated as SHA256 hashes.
type UserPreferences ¶ added in v0.16.0
type UserPreferences struct { // PreferredNamespace represents the namespace the user most recently authenticated with. PreferredNamespace string `json:"-" bson:"preferred_namespace"` }
type UserTokenRecover ¶ added in v0.7.2
type UserTokenRecover struct { Token string `json:"uid"` User string `json:"user_id"` CreatedAt time.Time `json:"created_at" bson:"created_at"` }
NOTE: This struct has been moved to the cloud repo as it is only used in a cloud context; however, it is also utilized by migrations. For this reason, we must maintain the struct here ensure everything continues to function as expected. TODO: Remove this struct when it is no longer needed for migrations.