Fix, placeholder image, api
Added a placeholder image, code style Fixed metadata missing issue More work on api
This commit is contained in:
parent
529d106351
commit
0e036b152b
8 changed files with 192 additions and 94 deletions
21
Code-Style.md
Normal file
21
Code-Style.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Code style guide
|
||||||
|
|
||||||
|
## Go
|
||||||
|
|
||||||
|
- Use `gofmt`
|
||||||
|
- `jsonapi` fields must use dasharised names
|
||||||
|
(eg `some-field` instead of `some_field` or `someField`)
|
||||||
|
- Function, struct and variable names must describe their purpose adequatly.
|
||||||
|
Making them longer for that purpose is fine
|
||||||
|
- Follow [https://go.dev/doc/effective_go]
|
||||||
|
(which also happens to be convenient place to start learning Go)
|
||||||
|
- Always use zerolog for console output. In http handlers,
|
||||||
|
use `hlog.FromRequest` to get a logger instance prepared with a bunch of metadata
|
||||||
|
- As Linstrom is both intended for active use as well as providing a learning resource,
|
||||||
|
all functions and structs must be documented
|
||||||
|
|
||||||
|
## JS/TS
|
||||||
|
|
||||||
|
<!-- TODO: Fill this out -->
|
||||||
|
|
||||||
|
- Biome should do most of the work
|
BIN
duck.webp
Normal file
BIN
duck.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
4
main.go
4
main.go
|
@ -27,6 +27,9 @@ var reactiveFS embed.FS
|
||||||
//go:embed frontend-noscript
|
//go:embed frontend-noscript
|
||||||
var nojsFS embed.FS
|
var nojsFS embed.FS
|
||||||
|
|
||||||
|
//go:embed duck.webp
|
||||||
|
var placeholderFile string
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
setLogger()
|
setLogger()
|
||||||
setLogLevel()
|
setLogLevel()
|
||||||
|
@ -76,6 +79,7 @@ func main() {
|
||||||
pkey,
|
pkey,
|
||||||
util.NewFSWrapper(reactiveFS, "frontend-reactive/dist/", false),
|
util.NewFSWrapper(reactiveFS, "frontend-reactive/dist/", false),
|
||||||
util.NewFSWrapper(nojsFS, "frontend-noscript/", false),
|
util.NewFSWrapper(nojsFS, "frontend-noscript/", false),
|
||||||
|
&placeholderFile,
|
||||||
)
|
)
|
||||||
server.Start(":8000")
|
server.Start(":8000")
|
||||||
// TODO: Set up media server
|
// TODO: Set up media server
|
||||||
|
|
|
@ -5,6 +5,7 @@ import "net/http"
|
||||||
func setupLinstromApiRouter() http.Handler {
|
func setupLinstromApiRouter() http.Handler {
|
||||||
router := http.NewServeMux()
|
router := http.NewServeMux()
|
||||||
router.Handle("/v1/", http.StripPrefix("/v1", setupLinstromApiV1Router()))
|
router.Handle("/v1/", http.StripPrefix("/v1", setupLinstromApiV1Router()))
|
||||||
|
router.Handle("/s2s/v1/", http.StripPrefix("/s2s/v1", setupLinstromS2SApiV1Router()))
|
||||||
|
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
@ -93,3 +94,10 @@ func setupLinstromApiV1Router() http.Handler {
|
||||||
|
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupLinstromS2SApiV1Router() http.Handler {
|
||||||
|
router := http.NewServeMux()
|
||||||
|
// TODO: Figure out a decent server to server API definition
|
||||||
|
router.HandleFunc("/", placeholderEndpoint)
|
||||||
|
return router
|
||||||
|
}
|
||||||
|
|
|
@ -165,7 +165,37 @@ func linstromUpdateAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Error().Err(err).Msg("Failed to marshal and write updated account")
|
log.Error().Err(err).Msg("Failed to marshal and write updated account")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {}
|
func linstromDeleteAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
|
actorId, _ := ActorIdFromRequest(r)
|
||||||
|
log := hlog.FromRequest(r)
|
||||||
|
store := StorageFromRequest(r)
|
||||||
|
targetAccountId := AccountIdFromRequest(r)
|
||||||
|
if targetAccountId != actorId {
|
||||||
|
other.HttpErr(w, HttpErrIdNotAuthenticated, "Action forbidden", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
acc, err := store.FindAccountById(targetAccountId)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("account-id", actorId).Msg("Failed to get account for deletion")
|
||||||
|
other.HttpErr(
|
||||||
|
w,
|
||||||
|
HttpErrIdDbFailure,
|
||||||
|
"Failed to get account from db",
|
||||||
|
http.StatusInternalServerError,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// allRoles, err := store.FindRolesByNames(acc.Roles)
|
||||||
|
// collapsedRole := storage.CollapseRolesIntoOne(allRoles...)
|
||||||
|
|
||||||
|
// TODO: Start job of sending out deletion messages to all federated servers
|
||||||
|
|
||||||
|
// Clean up related data first
|
||||||
|
// User role
|
||||||
|
// Custom fields
|
||||||
|
_ = acc
|
||||||
|
store.DeleteAccount(actorId)
|
||||||
|
}
|
||||||
|
|
||||||
func linstromIsFollowingAccount(w http.ResponseWriter, r *http.Request) {}
|
func linstromIsFollowingAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
func linstromFollowAccount(w http.ResponseWriter, r *http.Request) {}
|
func linstromFollowAccount(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
|
@ -23,10 +23,23 @@ func convertAccountStorageToLinstrom(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("icon: %w", err)
|
return nil, fmt.Errorf("icon: %w", err)
|
||||||
}
|
}
|
||||||
storageBanner, err := store.GetMediaMetadataById(acc.Banner)
|
var apiBanner *linstromMediaMetadata
|
||||||
|
if acc.Banner != nil {
|
||||||
|
storageBanner, err := store.GetMediaMetadataById(*acc.Banner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("banner: %w", err)
|
return nil, fmt.Errorf("banner: %w", err)
|
||||||
}
|
}
|
||||||
|
apiBanner = convertMediaMetadataStorageToLinstrom(storageBanner)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiBackground *linstromMediaMetadata
|
||||||
|
if acc.Background != nil {
|
||||||
|
storageBackground, err := store.GetMediaMetadataById(*acc.Background)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("banner: %w", err)
|
||||||
|
}
|
||||||
|
apiBackground = convertMediaMetadataStorageToLinstrom(storageBackground)
|
||||||
|
}
|
||||||
storageFields, err := store.FindMultipleUserFieldsById(acc.CustomFields)
|
storageFields, err := store.FindMultipleUserFieldsById(acc.CustomFields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("customFields: %w", err)
|
return nil, fmt.Errorf("customFields: %w", err)
|
||||||
|
@ -50,7 +63,11 @@ func convertAccountStorageToLinstrom(
|
||||||
IsBot: acc.IsBot,
|
IsBot: acc.IsBot,
|
||||||
Description: acc.Description,
|
Description: acc.Description,
|
||||||
Icon: convertMediaMetadataStorageToLinstrom(storageIcon),
|
Icon: convertMediaMetadataStorageToLinstrom(storageIcon),
|
||||||
Banner: convertMediaMetadataStorageToLinstrom(storageBanner),
|
IconId: acc.Icon,
|
||||||
|
Banner: apiBanner,
|
||||||
|
BannerId: acc.Banner,
|
||||||
|
Background: apiBackground,
|
||||||
|
BackgroundId: acc.Background,
|
||||||
FollowerIds: acc.Followers,
|
FollowerIds: acc.Followers,
|
||||||
FollowingIds: acc.Follows,
|
FollowingIds: acc.Follows,
|
||||||
Indexable: acc.Indexable,
|
Indexable: acc.Indexable,
|
||||||
|
|
|
@ -16,85 +16,89 @@ var (
|
||||||
type linstromNote struct {
|
type linstromNote struct {
|
||||||
Id string `jsonapi:"primary,notes"`
|
Id string `jsonapi:"primary,notes"`
|
||||||
RawContent string `jsonapi:"attr,content"`
|
RawContent string `jsonapi:"attr,content"`
|
||||||
OriginServer *linstromOriginServer `jsonapi:"relation,origin_server"`
|
OriginServer *linstromOriginServer `jsonapi:"relation,origin-server"`
|
||||||
OriginServerId int `jsonapi:"attr,origin_server_id"`
|
OriginServerId int `jsonapi:"attr,origin-server-id"`
|
||||||
ReactionCount string `jsonapi:"attr,reaction_count"`
|
ReactionCount string `jsonapi:"attr,reaction-count"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created-at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated-at,omitempty"`
|
||||||
Author *linstromAccount `jsonapi:"relation,author"`
|
Author *linstromAccount `jsonapi:"relation,author"`
|
||||||
AuthorId string `jsonapi:"attr,author_id"`
|
AuthorId string `jsonapi:"attr,author-id"`
|
||||||
ContentWarning *string `jsonapi:"attr,content_warning,omitempty"`
|
ContentWarning *string `jsonapi:"attr,content-warning,omitempty"`
|
||||||
InReplyToId *string `jsonapi:"attr,in_reply_to_id,omitempty"`
|
InReplyToId *string `jsonapi:"attr,in-reply-to-id,omitempty"`
|
||||||
QuotesId *string `jsonapi:"attr,quotes_id,omitempty"`
|
QuotesId *string `jsonapi:"attr,quotes-id,omitempty"`
|
||||||
EmoteIds []string `jsonapi:"attr,emotes,omitempty"`
|
EmoteIds []string `jsonapi:"attr,emotes,omitempty"`
|
||||||
Attachments []*linstromMediaMetadata `jsonapi:"relation,attachments,omitempty"`
|
Attachments []*linstromMediaMetadata `jsonapi:"relation,attachments,omitempty"`
|
||||||
AttachmentIds []string `jsonapi:"attr,attachment_ids"`
|
AttachmentIds []string `jsonapi:"attr,attachment-ids"`
|
||||||
AccessLevel uint8 `jsonapi:"attr,access_level"`
|
AccessLevel uint8 `jsonapi:"attr,access-level"`
|
||||||
Pings []*linstromAccount `jsonapi:"relation,pings,omitempty"`
|
Pings []*linstromAccount `jsonapi:"relation,pings,omitempty"`
|
||||||
PingIds []string `jsonapi:"attr,ping_ids,omitempty"`
|
PingIds []string `jsonapi:"attr,ping-ids,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type linstromOriginServer struct {
|
type linstromOriginServer struct {
|
||||||
Id uint `jsonapi:"primary,origins"`
|
Id uint `jsonapi:"primary,origins"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created-at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated-at,omitempty"`
|
||||||
ServerType string `jsonapi:"attr,server_type"` // one of "Linstrom", "Mastodon", "Plemora", "Misskey" or "Wafrn"
|
ServerType string `jsonapi:"attr,server-type"` // one of "Linstrom", "Mastodon", "Plemora", "Misskey" or "Wafrn"
|
||||||
Domain string `jsonapi:"attr,domain"`
|
Domain string `jsonapi:"attr,domain"`
|
||||||
DisplayName string `jsonapi:"attr,display_name"`
|
DisplayName string `jsonapi:"attr,display-name"`
|
||||||
Icon *linstromMediaMetadata `jsonapi:"relation,icon"`
|
Icon *linstromMediaMetadata `jsonapi:"relation,icon"`
|
||||||
IsSelf bool `jsonapi:"attr,is_self"`
|
IsSelf bool `jsonapi:"attr,is-self"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type linstromMediaMetadata struct {
|
type linstromMediaMetadata struct {
|
||||||
Id string `jsonapi:"primary,medias"`
|
Id string `jsonapi:"primary,media"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created-at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated-at,omitempty"`
|
||||||
IsRemote bool `jsonapi:"attr,is_remote"`
|
IsRemote bool `jsonapi:"attr,is-remote"`
|
||||||
Url string `jsonapi:"attr,url"`
|
Url string `jsonapi:"attr,url"`
|
||||||
MimeType string `jsonapi:"attr,mime_type"`
|
MimeType string `jsonapi:"attr,mime-type"`
|
||||||
Name string `jsonapi:"attr,name"`
|
Name string `jsonapi:"attr,name"`
|
||||||
AltText string `jsonapi:"attr,alt_text"`
|
AltText string `jsonapi:"attr,alt-text"`
|
||||||
Blurred bool `jsonapi:"attr,blurred"`
|
Blurred bool `jsonapi:"attr,blurred"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type linstromAccount struct {
|
type linstromAccount struct {
|
||||||
Id string `jsonapi:"primary,accounts"`
|
Id string `jsonapi:"primary,accounts"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created-at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated-at,omitempty"`
|
||||||
Username string `jsonapi:"attr,username"`
|
Username string `jsonapi:"attr,username"`
|
||||||
OriginServer *linstromOriginServer `jsonapi:"relation,origin_server"`
|
OriginServer *linstromOriginServer `jsonapi:"relation,origin-server"`
|
||||||
OriginServerId int `jsonapi:"attr,origin_server_id"`
|
OriginServerId int `jsonapi:"attr,origin-server-id"`
|
||||||
DisplayName string `jsonapi:"attr,display_name"`
|
DisplayName string `jsonapi:"attr,display-name"`
|
||||||
CustomFields []*linstromCustomAccountField `jsonapi:"relation,custom_fields"`
|
CustomFields []*linstromCustomAccountField `jsonapi:"relation,custom-fields"`
|
||||||
CustomFieldIds []uint `jsonapi:"attr,custom_field_ids"`
|
CustomFieldIds []uint `jsonapi:"attr,custom-field-ids"`
|
||||||
IsBot bool `jsonapi:"attr,is_bot"`
|
IsBot bool `jsonapi:"attr,is-bot"`
|
||||||
Description string `jsonapi:"attr,description"`
|
Description string `jsonapi:"attr,description"`
|
||||||
Icon *linstromMediaMetadata `jsonapi:"relation,icon"`
|
Icon *linstromMediaMetadata `jsonapi:"relation,icon"`
|
||||||
|
IconId string `jsonapi:"attr,icon-id"`
|
||||||
Banner *linstromMediaMetadata `jsonapi:"relation,banner"`
|
Banner *linstromMediaMetadata `jsonapi:"relation,banner"`
|
||||||
FollowerIds []string `jsonapi:"attr,follows_ids"`
|
BannerId *string `jsonapi:"attr,banner-id"`
|
||||||
FollowingIds []string `jsonapi:"attr,following_ids"`
|
Background *linstromMediaMetadata `jsonapi:"relation,background"`
|
||||||
|
BackgroundId *string `jsonapi:"attr,background-id"`
|
||||||
|
FollowerIds []string `jsonapi:"attr,follows-ids"`
|
||||||
|
FollowingIds []string `jsonapi:"attr,following-ids"`
|
||||||
Indexable bool `jsonapi:"attr,indexable"`
|
Indexable bool `jsonapi:"attr,indexable"`
|
||||||
RestrictedFollow bool `jsonapi:"attr,restricted_follow"`
|
RestrictedFollow bool `jsonapi:"attr,restricted-follow"`
|
||||||
IdentifiesAs []string `jsonapi:"attr,identifies_as"`
|
IdentifiesAs []string `jsonapi:"attr,identifies-as"`
|
||||||
Pronouns []string `jsonapi:"attr,pronouns"`
|
Pronouns []string `jsonapi:"attr,pronouns"`
|
||||||
Roles []string `jsonapi:"attr,roles"`
|
Roles []string `jsonapi:"attr,roles"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type linstromCustomAccountField struct {
|
type linstromCustomAccountField struct {
|
||||||
Id uint `jsonapi:"primary,custom_account_fields"`
|
Id uint `jsonapi:"primary,custom-account-fields"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created-at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated-at,omitempty"`
|
||||||
Key string `jsonapi:"attr,key"`
|
Key string `jsonapi:"attr,key"`
|
||||||
Value string `jsonapi:"attr,value"`
|
Value string `jsonapi:"attr,value"`
|
||||||
Verified *bool `jsonapi:"attr,verified,omitempty"`
|
Verified *bool `jsonapi:"attr,verified,omitempty"`
|
||||||
BelongsToId string `jsonapi:"attr,belongs_to_id"`
|
BelongsToId string `jsonapi:"attr,belongs-to-id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Role is essentially just a carbon copy of storage/roles.go
|
// Role is essentially just a carbon copy of storage/roles.go
|
||||||
type linstromRole struct {
|
type linstromRole struct {
|
||||||
Id uint `jsonapi:"primary,roles"`
|
Id uint `jsonapi:"primary,roles"`
|
||||||
CreatedAt time.Time `jsonapi:"attr,created_at"`
|
CreatedAt time.Time `jsonapi:"attr,created-at"`
|
||||||
UpdatedAt *time.Time `jsonapi:"attr,updated_at,omitempty"`
|
UpdatedAt *time.Time `jsonapi:"attr,updated-at,omitempty"`
|
||||||
|
|
||||||
// Name of the role
|
// Name of the role
|
||||||
Name string `jsonapi:"attr,name"`
|
Name string `jsonapi:"attr,name"`
|
||||||
|
@ -107,35 +111,35 @@ type linstromRole struct {
|
||||||
Priority uint `jsonapi:"attr,priority"`
|
Priority uint `jsonapi:"attr,priority"`
|
||||||
// Whether this role is for a for a single user only (like custom, per user permissions in Discord)
|
// Whether this role is for a for a single user only (like custom, per user permissions in Discord)
|
||||||
// If yes, Name will be the id of the user in question
|
// If yes, Name will be the id of the user in question
|
||||||
IsUserRole bool `jsonapi:"attr,is_user_role"`
|
IsUserRole bool `jsonapi:"attr,is-user-role"`
|
||||||
|
|
||||||
// Whether this role is one built into Linstrom from the start or not
|
// Whether this role is one built into Linstrom from the start or not
|
||||||
// Note: Built-in roles can't be modified
|
// Note: Built-in roles can't be modified
|
||||||
IsBuiltIn bool `jsonapi:"attr,is_builtin"`
|
IsBuiltIn bool `jsonapi:"attr,is-builtin"`
|
||||||
|
|
||||||
// --- User permissions ---
|
// --- User permissions ---
|
||||||
CanSendMedia *bool `jsonapi:"attr,can_send_media"`
|
CanSendMedia *bool `jsonapi:"attr,can-send-media"`
|
||||||
CanSendCustomEmotes *bool `jsonapi:"attr,can_send_custom_emotes"`
|
CanSendCustomEmotes *bool `jsonapi:"attr,can-send-custom-emotes"`
|
||||||
CanSendCustomReactions *bool `jsonapi:"attr,can_send_custom_reactions"`
|
CanSendCustomReactions *bool `jsonapi:"attr,can-send-custom-reactions"`
|
||||||
CanSendPublicNotes *bool `jsonapi:"attr,can_send_public_notes"`
|
CanSendPublicNotes *bool `jsonapi:"attr,can-send-public-notes"`
|
||||||
CanSendLocalNotes *bool `jsonapi:"attr,can_send_local_notes"`
|
CanSendLocalNotes *bool `jsonapi:"attr,can-send-local-notes"`
|
||||||
CanSendFollowerOnlyNotes *bool `jsonapi:"attr,can_send_follower_only_notes"`
|
CanSendFollowerOnlyNotes *bool `jsonapi:"attr,can-send-follower-only-notes"`
|
||||||
CanSendPrivateNotes *bool `jsonapi:"attr,can_send_private_notes"`
|
CanSendPrivateNotes *bool `jsonapi:"attr,can-send-private-notes"`
|
||||||
CanSendReplies *bool `jsonapi:"attr,can_send_replies"`
|
CanSendReplies *bool `jsonapi:"attr,can-send-replies"`
|
||||||
CanQuote *bool `jsonapi:"attr,can_quote"`
|
CanQuote *bool `jsonapi:"attr,can-quote"`
|
||||||
CanBoost *bool `jsonapi:"attr,can_boost"`
|
CanBoost *bool `jsonapi:"attr,can-boost"`
|
||||||
CanIncludeLinks *bool `jsonapi:"attr,can_include_links"`
|
CanIncludeLinks *bool `jsonapi:"attr,can-include-links"`
|
||||||
CanIncludeSurvey *bool `jsonapi:"attr,can_include_survey"`
|
CanIncludeSurvey *bool `jsonapi:"attr,can-include-survey"`
|
||||||
|
|
||||||
CanChangeDisplayName *bool `jsonapi:"attr,can_change_display_name"`
|
CanChangeDisplayName *bool `jsonapi:"attr,can-change-display-name"`
|
||||||
|
|
||||||
BlockedUsers []string `jsonapi:"attr,blocked_users"`
|
BlockedUsers []string `jsonapi:"attr,blocked-users"`
|
||||||
CanSubmitReports *bool `jsonapi:"attr,can_submit_reports"`
|
CanSubmitReports *bool `jsonapi:"attr,can-submit-reports"`
|
||||||
CanLogin *bool `jsonapi:"attr,can_login"`
|
CanLogin *bool `jsonapi:"attr,can-login"`
|
||||||
|
|
||||||
CanMentionOthers *bool `jsonapi:"attr,can_mention_others"`
|
CanMentionOthers *bool `jsonapi:"attr,can-mention-others"`
|
||||||
HasMentionCountLimit *bool `jsonapi:"attr,has_mention_count_limit"`
|
HasMentionCountLimit *bool `jsonapi:"attr,has-mention-count-limit"`
|
||||||
MentionLimit *uint32 `jsonapi:"attr,mention_count_limit"`
|
MentionLimit *uint32 `jsonapi:"attr,mention-count-limit"`
|
||||||
|
|
||||||
// CanViewBoosts *bool
|
// CanViewBoosts *bool
|
||||||
// CanViewQuotes *bool
|
// CanViewQuotes *bool
|
||||||
|
@ -143,32 +147,32 @@ type linstromRole struct {
|
||||||
// CanViewCustomEmotes *bool
|
// CanViewCustomEmotes *bool
|
||||||
|
|
||||||
// --- Automod ---
|
// --- Automod ---
|
||||||
AutoNsfwMedia *bool `jsonapi:"attr,auto_nsfw_media"`
|
AutoNsfwMedia *bool `jsonapi:"attr,auto-nsfw-media"`
|
||||||
AutoCwPosts *bool `jsonapi:"attr,auto_cw_posts"`
|
AutoCwPosts *bool `jsonapi:"attr,auto-cw-posts"`
|
||||||
AutoCwPostsText *string `jsonapi:"attr,auto_cw_posts_text"`
|
AutoCwPostsText *string `jsonapi:"attr,auto-cw-posts-text"`
|
||||||
ScanCreatedPublicNotes *bool `jsonapi:"attr,scan_created_public_notes"`
|
ScanCreatedPublicNotes *bool `jsonapi:"attr,scan-created-public-notes"`
|
||||||
ScanCreatedLocalNotes *bool `jsonapi:"attr,scan_created_local_notes"`
|
ScanCreatedLocalNotes *bool `jsonapi:"attr,scan-created-local-notes"`
|
||||||
ScanCreatedFollowerOnlyNotes *bool `jsonapi:"attr,scan_created_follower_only_notes"`
|
ScanCreatedFollowerOnlyNotes *bool `jsonapi:"attr,scan-created-follower-only-notes"`
|
||||||
ScanCreatedPrivateNotes *bool `jsonapi:"attr,scan_created_private_notes"`
|
ScanCreatedPrivateNotes *bool `jsonapi:"attr,scan-created-private-notes"`
|
||||||
DisallowInteractionsWith []string `jsonapi:"attr,disallow_interactions_with"`
|
DisallowInteractionsWith []string `jsonapi:"attr,disallow-interactions-with"`
|
||||||
|
|
||||||
WithholdNotesForManualApproval *bool `jsonapi:"attr,withhold_notes_for_manual_approval"`
|
WithholdNotesForManualApproval *bool `jsonapi:"attr,withhold-notes-for-manual-approval"`
|
||||||
WithholdNotesBasedOnRegex *bool `jsonapi:"attr,withhold_notes_based_on_regex"`
|
WithholdNotesBasedOnRegex *bool `jsonapi:"attr,withhold-notes-based-on-regex"`
|
||||||
WithholdNotesRegexes []string `jsonapi:"attr,withhold_notes_regexes"`
|
WithholdNotesRegexes []string `jsonapi:"attr,withhold-notes-regexes"`
|
||||||
|
|
||||||
// --- Admin perms ---
|
// --- Admin perms ---
|
||||||
// If set, counts as all permissions being set as given and all restrictions being disabled
|
// If set, counts as all permissions being set as given and all restrictions being disabled
|
||||||
FullAdmin *bool `jsonapi:"attr,full_admin"`
|
FullAdmin *bool `jsonapi:"attr,full-admin"`
|
||||||
CanAffectOtherAdmins *bool `jsonapi:"attr,can_affect_other_admins"`
|
CanAffectOtherAdmins *bool `jsonapi:"attr,can-affect-other-admins"`
|
||||||
CanDeleteNotes *bool `jsonapi:"attr,can_delete_notes"`
|
CanDeleteNotes *bool `jsonapi:"attr,can-delete-notes"`
|
||||||
CanConfirmWithheldNotes *bool `jsonapi:"attr,can_confirm_withheld_notes"`
|
CanConfirmWithheldNotes *bool `jsonapi:"attr,can-confirm-withheld-notes"`
|
||||||
CanAssignRoles *bool `jsonapi:"attr,can_assign_roles"`
|
CanAssignRoles *bool `jsonapi:"attr,can-assign-roles"`
|
||||||
CanSupressInteractionsBetweenUsers *bool `jsonapi:"attr,can_supress_interactions_between_users"`
|
CanSupressInteractionsBetweenUsers *bool `jsonapi:"attr,can-supress-interactions-between-users"`
|
||||||
CanOverwriteDisplayNames *bool `jsonapi:"attr,can_overwrite_display_names"`
|
CanOverwriteDisplayNames *bool `jsonapi:"attr,can-overwrite-display-names"`
|
||||||
CanManageCustomEmotes *bool `jsonapi:"attr,can_manage_custom_emotes"`
|
CanManageCustomEmotes *bool `jsonapi:"attr,can-manage-custom-emotes"`
|
||||||
CanViewDeletedNotes *bool `jsonapi:"attr,can_view_deleted_notes"`
|
CanViewDeletedNotes *bool `jsonapi:"attr,can-view-deleted-notes"`
|
||||||
CanRecoverDeletedNotes *bool `jsonapi:"attr,can_recover_deleted_notes"`
|
CanRecoverDeletedNotes *bool `jsonapi:"attr,can-recover-deleted-notes"`
|
||||||
CanManageAvatarDecorations *bool `jsonapi:"attr,can_manage_avatar_decorations"`
|
CanManageAvatarDecorations *bool `jsonapi:"attr,can-manage-avatar-decorations"`
|
||||||
CanManageAds *bool `jsonapi:"attr,can_manage_ads"`
|
CanManageAds *bool `jsonapi:"attr,can-manage-ads"`
|
||||||
CanSendAnnouncements *bool `jsonapi:"attr,can_send_announcements"`
|
CanSendAnnouncements *bool `jsonapi:"attr,can-send-announcements"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -15,8 +16,13 @@ type Server struct {
|
||||||
router http.Handler
|
router http.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(store *storage.Storage, pkey *passkey.Passkey, reactiveFS, staticFS fs.FS) *Server {
|
func NewServer(
|
||||||
handler := buildRootHandler(pkey, reactiveFS, staticFS)
|
store *storage.Storage,
|
||||||
|
pkey *passkey.Passkey,
|
||||||
|
reactiveFS, staticFS fs.FS,
|
||||||
|
placeholderFile *string,
|
||||||
|
) *Server {
|
||||||
|
handler := buildRootHandler(pkey, reactiveFS, staticFS, placeholderFile)
|
||||||
handler = ChainMiddlewares(handler, LoggingMiddleware, ContextValsMiddleware(map[any]any{
|
handler = ChainMiddlewares(handler, LoggingMiddleware, ContextValsMiddleware(map[any]any{
|
||||||
ContextKeyStorage: store,
|
ContextKeyStorage: store,
|
||||||
}))
|
}))
|
||||||
|
@ -26,7 +32,11 @@ func NewServer(store *storage.Storage, pkey *passkey.Passkey, reactiveFS, static
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildRootHandler(pkey *passkey.Passkey, reactiveFS, staticFS fs.FS) http.Handler {
|
func buildRootHandler(
|
||||||
|
pkey *passkey.Passkey,
|
||||||
|
reactiveFS, staticFS fs.FS,
|
||||||
|
placeholderFile *string,
|
||||||
|
) http.Handler {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle(
|
mux.Handle(
|
||||||
"/webauthn/",
|
"/webauthn/",
|
||||||
|
@ -61,6 +71,10 @@ func buildRootHandler(pkey *passkey.Passkey, reactiveFS, staticFS fs.FS) http.Ha
|
||||||
)(ChainMiddlewares(setupTestEndpoints(), passkeyIdToAccountIdTransformerMiddleware)),
|
)(ChainMiddlewares(setupTestEndpoints(), passkeyIdToAccountIdTransformerMiddleware)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mux.HandleFunc("/placeholder-file", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprint(w, placeholderFile)
|
||||||
|
})
|
||||||
|
|
||||||
return mux
|
return mux
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue