Documentation
¶
Index ¶
- type BanInput
- type BanStatus
- type Device
- type FollowBlockRequest
- type FollowRequestGroup
- type FollowRequestIn
- type FollowResponse
- type FollowStorer
- type Follower
- type Input
- type Member
- type PgMemberStorage
- func (s *PgMemberStorage) AcceptFollow(ctx context.Context, accepter string, requestID int64) error
- func (s *PgMemberStorage) Ban(ctx context.Context, member *Member, input *BanInput) (err error)
- func (s *PgMemberStorage) CacheNicknames(ctx context.Context) error
- func (s *PgMemberStorage) CancelFollow(ctx context.Context, requester string, requestID int64) error
- func (s *PgMemberStorage) Check(c context.Context, email, nickname string) (bool, error)
- func (s *PgMemberStorage) CreateSession(ctx context.Context, m *Member) (t string, err error)
- func (s *PgMemberStorage) Delete(ctx context.Context, member *Member) error
- func (s *PgMemberStorage) GetFollowRequests(ctx context.Context, member string, kind string) (any, error)
- func (s *PgMemberStorage) GetFollowStatus(ctx context.Context, follower, followee string) FollowResponse
- func (s *PgMemberStorage) GetID(ctx context.Context, credential string) (id int, err error)
- func (s *PgMemberStorage) GetNicknames() []string
- func (s *PgMemberStorage) GetPassHash(email, login string) (string, error)
- func (s *PgMemberStorage) HasRole(ctx context.Context, name, role string, exact bool) bool
- func (s *PgMemberStorage) IsBlocked(ctx context.Context, fr *FollowBlockRequest) (blocked bool, err error)
- func (s *PgMemberStorage) Read(ctx context.Context, value string, keyNames ...string) (*Member, error)
- func (s *PgMemberStorage) RejectFollow(ctx context.Context, rejecter string, requestID int64) error
- func (s *PgMemberStorage) RemoveFollower(ctx context.Context, follower, followee string) error
- func (s *PgMemberStorage) RequestFollow(ctx context.Context, fr *FollowBlockRequest) FollowResponse
- func (s *PgMemberStorage) Save(ctx context.Context, member *Member) error
- func (s *PgMemberStorage) Unban(ctx context.Context, member *Member) error
- func (s *PgMemberStorage) Update(ctx context.Context, member *Member) error
- func (s *PgMemberStorage) VerifyViewability(ctx context.Context, viewer, viewee string) (bool, error)
- type Preferences
- type PrivacySecurityPreferences
- type Storer
- type UXPreferences
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BanInput ¶ added in v0.9.0
type BanInput struct {
Reason string `json:"reason" db:"reason" validate:"required" example:"spam"`
Ends time.Time `json:"ends" db:"ends" validate:"required" example:"2038-01-16T00:00:00Z"`
CanAppeal bool `json:"canAppeal" db:"can_appeal" validate:"required" example:"true"`
// usage: https://pkg.go.dev/net#ParseCIDR
Mask *net.IPNet `json:"mask" db:"mask"`
}
BanInput is used to ban a member
type BanStatus ¶ added in v0.7.0
type BanStatus struct {
BanInput
MemberUUID uuid.UUID `json:"memberUUID" db:"member_uuid"`
// Occurrence is the n-th time a ban has been issued
Occurrence int16 `json:"occurrence" db:"occurrence"`
Started time.Time `json:"started" db:"started"`
}
BanStatus is used to retrieve the ban details
type Device ¶ added in v0.7.0
type Device struct {
FriendlyName sql.NullString `json:"friendlyName,omitempty" db:"friendly_name"`
// KnownIPs is used to improve the security in case of logging in from unknown locations
KnownIPs []net.IP `json:"knownIPs,omitempty" db:"known_ips"`
LastLogin time.Time `json:"lastLogin,omitempty" db:"last_login"`
BanStatus BanStatus `json:"banStatus,omitempty" db:"ban_status"`
ID uuid.UUID `json:"id" db:"id,unique,notnull"`
}
Member holds the core information about a member
type FollowBlockRequest ¶ added in v0.9.0
type FollowBlockRequest struct {
ID int64 `json:"id,omitempty" db:"id"`
Requester string `json:"requester,omitempty" db:"requester_webfinger"`
Target string `json:"target" db:"target_webfinger"`
Reblogs bool `json:"reblogs" db:"reblogs" default:"true" sql:"-"` // only used for follow requests
Notify bool `json:"notify" db:"notify" default:"true" sql:"-"`
Created time.Time `json:"created,omitempty" db:"created"`
}
Member holds the core information about a member
type FollowRequestGroup ¶ added in v0.9.0
type FollowRequestGroup struct {
Sent []FollowResponse `json:"sent" db:"sent"`
Received []FollowRequestIn `json:"received" db:"received"`
}
Member holds the core information about a member
type FollowRequestIn ¶ added in v0.9.0
type FollowRequestIn struct {
ID int64 `json:"id" db:"id"`
Requester string `json:"requester" db:"requester_webfinger"`
Created *time.Time `json:"created" db:"created"`
}
received follow request
type FollowResponse ¶ added in v0.9.0
type FollowResponse struct {
// when checking status, we treat not_found as not following
// but when creating a request, we treat not_found as target account not existing
Status string `json:"status" db:"status", validate:"required,oneof=accepted failed pending blocked already_following not_found"`
ID int64 `json:"id,omitempty" db:"id"`
Reblogs bool `json:"reblogs,omitempty" db:"reblogs"`
Notify bool `json:"notify,omitempty" db:"notify"`
Error error `json:"-"`
AcceptTime *time.Time `json:"acceptTime" db:"created"`
}
Member holds the core information about a member
type FollowStorer ¶ added in v0.9.0
type FollowStorer interface {
RequestFollow(ctx context.Context, fr *FollowBlockRequest) FollowResponse
// UpdateFollow(ctx context.Context, fr *FollowBlockRequest) error
AcceptFollow(ctx context.Context, accepter string, requestID int64) error
CancelFollow(ctx context.Context, canceler string, requestID int64) error
RejectFollow(ctx context.Context, rejecter string, requestID int64) error
GetFollowStatus(ctx context.Context, follower, followee string) FollowResponse
GetFollowRequests(ctx context.Context, member string, reqType string) (any, error)
RemoveFollower(ctx context.Context, follower, followee string) error
}
Member holds the core information about a member
type Follower ¶
type Follower struct {
ID uint32 `json:"id" db:"id"`
Created time.Time `json:"created" db:"created"`
Follower string `json:"follower" db:"follower"`
Followee string `json:"followee" db:"followee"`
}
Follower represents a follower-followee relationship
type Input ¶
type Input struct {
MemberName string `json:"membername"`
Email string `json:"email"`
Password string `json:"password"`
}
Input holds the information required to create a new member account
type Member ¶
type Member struct {
ID int `json:"-" db:"id"`
UUID uuid.UUID `json:"uuid,omitempty" db:"uuid"`
PassHash string `json:"-" db:"passhash"`
// MemberName != webfinger
MemberName string `json:"memberName" db:"nick,unique" validate:"required,alphanumunicode,min=3,max=30" example:"lain"`
// email like
Webfinger string `json:"webfinger" db:"webfinger,unique" validate:"required,email" example:"lain@librate.club"`
DisplayName sql.NullString `json:"displayName,omitempty" db:"display_name" example:"Lain Iwakura"`
Email string `json:"email" db:"email" validate:"required,email" example:"lain@wired.jp"`
Bio sql.NullString `json:"bio,omitempty" db:"bio" example:"Wherever you go, everyone is connected."`
Active bool `json:"active" db:"active" example:"true"`
Roles pq.StringArray `json:"roles,omitempty" db:"roles" example:"[\"admin\", \"moderator\"]"`
RegTimestamp time.Time `json:"regdate" db:"reg_timestamp" example:"2020-01-01T00:00:00Z"`
ProfilePicID sql.NullInt64 `json:"-" db:"profilepic_id"`
ProfilePicSource string `json:"profile_pic,omitempty" db:"-" example:"/static/img/profile/lain.jpg"`
Homepage sql.NullString `json:"homepage,omitempty" db:"homepage" example:"https://webnavi.neocities.org/"`
// doomed fields, will be removed by arbitrary user-defined fields
IRC sql.NullString `json:"irc,omitempty" db:"irc"`
XMPP sql.NullString `json:"xmpp,omitempty" db:"xmpp"`
Matrix sql.NullString `json:"matrix,omitempty" db:"matrix"`
Visibility string `json:"visibility" db:"visibility" example:"followers_only"`
FollowingURI string `json:"following_uri" db:"following_uri"` // URI for getting the following list of this account
FollowersURI string `json:"followers_uri" db:"followers_uri"` // URI for getting the followers list of this account
SessionTimeout sql.NullInt64 `json:"-" db:"session_timeout"`
PublicKeyPem string `jsonld:"publicKeyPem,omitempty" json:"publicKeyPem" db:"public_key_pem"`
}
Member holds the core information about a member
type PgMemberStorage ¶
type PgMemberStorage struct {
// contains filtered or unexported fields
}
Member holds the core information about a member
func NewSQLStorage ¶
func (*PgMemberStorage) AcceptFollow ¶ added in v0.9.0
func (*PgMemberStorage) CacheNicknames ¶
func (s *PgMemberStorage) CacheNicknames(ctx context.Context) error
func (*PgMemberStorage) CancelFollow ¶ added in v0.9.0
func (*PgMemberStorage) Check ¶ added in v0.7.0
Check checks if a member with the given email or nickname already exists
func (*PgMemberStorage) CreateSession ¶
CreateSession creates a JWT token for the member
func (*PgMemberStorage) Delete ¶
func (s *PgMemberStorage) Delete(ctx context.Context, member *Member) error
func (*PgMemberStorage) GetFollowRequests ¶ added in v0.9.0
func (*PgMemberStorage) GetFollowStatus ¶ added in v0.9.0
func (s *PgMemberStorage) GetFollowStatus(ctx context.Context, follower, followee string) FollowResponse
func (*PgMemberStorage) GetID ¶
GetID retrieves the ID required for JWT on the basis of one of the credentials, i.e. email or login
func (*PgMemberStorage) GetNicknames ¶
func (s *PgMemberStorage) GetNicknames() []string
func (*PgMemberStorage) GetPassHash ¶
func (s *PgMemberStorage) GetPassHash(email, login string) (string, error)
GetPassHash retrieves the password hash required for JWT on the basis of one of the credentials, i.e. email or login
func (*PgMemberStorage) HasRole ¶ added in v0.9.0
if exact is true, the role must match exactly otherwise we can match moderators with admins on tasks that can be performed by both
func (*PgMemberStorage) IsBlocked ¶ added in v0.9.0
func (s *PgMemberStorage) IsBlocked(ctx context.Context, fr *FollowBlockRequest) (blocked bool, err error)
func (*PgMemberStorage) RejectFollow ¶ added in v0.9.0
TODO: add option to send a note to the requester stating the reason for rejection
func (*PgMemberStorage) RemoveFollower ¶ added in v0.9.0
func (s *PgMemberStorage) RemoveFollower(ctx context.Context, follower, followee string) error
RemoveFollower handles both the followee and follower initiated removal of a follower due to the reciprocal nature of the relationship It can also deal with cancelling pending follow requests
func (*PgMemberStorage) RequestFollow ¶
func (s *PgMemberStorage) RequestFollow(ctx context.Context, fr *FollowBlockRequest) FollowResponse
RequestFollow creates a follow request in the local database upon the reception of a request into the inbox
func (*PgMemberStorage) Save ¶
func (s *PgMemberStorage) Save(ctx context.Context, member *Member) error
func (*PgMemberStorage) Unban ¶ added in v0.9.0
func (s *PgMemberStorage) Unban(ctx context.Context, member *Member) error
func (*PgMemberStorage) Update ¶
func (s *PgMemberStorage) Update(ctx context.Context, member *Member) error
func (*PgMemberStorage) VerifyViewability ¶ added in v0.9.0
func (s *PgMemberStorage) VerifyViewability(ctx context.Context, viewer, viewee string) (bool, error)
viewer and viewee are both identified by webfinger
type Preferences ¶ added in v0.9.0
type Preferences struct {
// NOTE:not using DB tags since the structure for this is actually flat in the DB
UX UXPreferences `json:"ux,omitempty"`
PrivacySecurity PrivacySecurityPreferences `json:"privsec,omitempty"`
}
TODO: move the password here
type PrivacySecurityPreferences ¶ added in v0.9.0
type PrivacySecurityPreferences struct {
MessageAutohideWords pq.StringArray `json:"message_autohide_words,omitempty" db:"message_autohide_words"`
// domain names alone, without protocol etc.
MutedInstances pq.StringArray `json:"muted_instances,omitempty" db:"muted_instances"`
AutoAcceptFollow bool `json:"auto_accept_follow,omitempty" db:"auto_accept_follow" default:"true"`
LocallySearchable bool `json:"locally_searchable,omitempty" db:"locally_searchable" default:"true"`
FederatedSearchable bool `json:"searchable_to_federated,omitempty" db:"searchable_to_federated" default:"true"`
RobotsSearchable bool `json:"robots_searchable,omitempty" db:"robots_searchable" default:"false"`
}
Member holds the core information about a member
type Storer ¶ added in v0.9.0
type Storer interface {
Save(ctx context.Context, member *Member) error
Read(ctx context.Context, key string, keyNames ...string) (*Member, error)
HasRole(ctx context.Context, name, role string, exact bool) bool
Ban(ctx context.Context, member *Member, input *BanInput) error
Unban(ctx context.Context, member *Member) error
VerifyViewability(ctx context.Context, viewer, viewee string) (bool, error)
// Check checks if a member with the given email or nickname already exists
Check(ctx context.Context, email, nickname string) (bool, error)
Update(ctx context.Context, member *Member) error
Delete(ctx context.Context, member *Member) error
GetID(ctx context.Context, key string) (int, error)
GetPassHash(email, login string) (string, error)
CreateSession(ctx context.Context, member *Member) (string, error)
IsBlocked(ctx context.Context, fr *FollowBlockRequest) (blocked bool, err error)
FollowStorer
}
TODO: debload this interface
type UXPreferences ¶ added in v0.9.0
type UXPreferences struct {
Locale language.Tag `json:"locale,omitempty" db:"locale"`
// everything is calculated relative to the maximum scale of 0-100
RatingScaleLower int16 `json:"rating_scale_lower,omitempty" db:"rating_scale_lower" validate:"ltfield=RatinScaleUpper",min=0,max=1" default:"1"`
RatingScaleUpper int16 `json:"rating_scale_upper,omitempty" db:"rating_scale_upper" validate:"min=2,max=100" default:"10"`
}
Theme is stored in localStorage since some people might prefer to have a different theme on different devices