More fixes
This commit is contained in:
@@ -32,18 +32,15 @@ var (
|
|||||||
|
|
||||||
// API ...
|
// API ...
|
||||||
type API struct {
|
type API struct {
|
||||||
router *Router
|
router *Router
|
||||||
config *Config
|
config *Config
|
||||||
cache *Cache
|
db Store
|
||||||
archive Archiver
|
pm passwords.Passwords
|
||||||
db Store
|
|
||||||
pm passwords.Passwords
|
|
||||||
tasks *Dispatcher
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAPI ...
|
// NewAPI ...
|
||||||
func NewAPI(router *Router, config *Config, cache *Cache, archive Archiver, db Store, pm passwords.Passwords, tasks *Dispatcher) *API {
|
func NewAPI(router *Router, config *Config, db Store, pm passwords.Passwords) *API {
|
||||||
api := &API{router, config, cache, archive, db, pm, tasks}
|
api := &API{router, config, db, pm}
|
||||||
|
|
||||||
api.initRoutes()
|
api.initRoutes()
|
||||||
|
|
||||||
@@ -54,11 +51,6 @@ func (a *API) initRoutes() {
|
|||||||
router := a.router.Group("/api/v1")
|
router := a.router.Group("/api/v1")
|
||||||
|
|
||||||
router.GET("/ping", a.PingEndpoint())
|
router.GET("/ping", a.PingEndpoint())
|
||||||
router.POST("/auth", a.AuthEndpoint())
|
|
||||||
|
|
||||||
// Support / Report endpoints
|
|
||||||
router.POST("/support", a.isAuthorized(a.SupportEndpoint()))
|
|
||||||
router.POST("/report", a.isAuthorized(a.ReportEndpoint()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateToken ...
|
// CreateToken ...
|
||||||
@@ -116,14 +108,6 @@ func (a *API) getLoggedInUser(r *http.Request) *User {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every registered new user follows themselves
|
|
||||||
// TODO: Make this configurable server behaviour?
|
|
||||||
if user.Following == nil {
|
|
||||||
user.Following = make(map[string]string)
|
|
||||||
}
|
|
||||||
|
|
||||||
user.Following[user.Username] = user.URL
|
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -154,13 +138,6 @@ func (a *API) isAuthorized(endpoint httprouter.Handle) httprouter.Handle {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every registered new user follows themselves
|
|
||||||
// TODO: Make this configurable server behaviour?
|
|
||||||
if user.Following == nil {
|
|
||||||
user.Following = make(map[string]string)
|
|
||||||
}
|
|
||||||
user.Following[user.Username] = user.URL
|
|
||||||
|
|
||||||
ctx := context.WithValue(r.Context(), TokenContextKey, token)
|
ctx := context.WithValue(r.Context(), TokenContextKey, token)
|
||||||
ctx = context.WithValue(ctx, UserContextKey, user)
|
ctx = context.WithValue(ctx, UserContextKey, user)
|
||||||
|
|
||||||
|
|||||||
@@ -77,79 +77,6 @@ func (bs *BitcaskStore) DelFeed(name string) error {
|
|||||||
return bs.db.Delete(key)
|
return bs.db.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bs *BitcaskStore) GetFeed(name string) (*Feed, error) {
|
|
||||||
key := []byte(fmt.Sprintf("%s/%s", feedsKeyPrefix, name))
|
|
||||||
data, err := bs.db.Get(key)
|
|
||||||
if err == bitcask.ErrKeyNotFound {
|
|
||||||
return nil, ErrFeedNotFound
|
|
||||||
}
|
|
||||||
return LoadFeed(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bs *BitcaskStore) SetFeed(name string, feed *Feed) error {
|
|
||||||
data, err := feed.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
key := []byte(fmt.Sprintf("%s/%s", feedsKeyPrefix, name))
|
|
||||||
if err := bs.db.Put(key, data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bs *BitcaskStore) LenFeeds() int64 {
|
|
||||||
var count int64
|
|
||||||
|
|
||||||
if err := bs.db.Scan([]byte(feedsKeyPrefix), func(_ []byte) error {
|
|
||||||
count++
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
log.WithError(err).Error("error scanning")
|
|
||||||
}
|
|
||||||
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bs *BitcaskStore) SearchFeeds(prefix string) []string {
|
|
||||||
var keys []string
|
|
||||||
|
|
||||||
if err := bs.db.Scan([]byte(feedsKeyPrefix), func(key []byte) error {
|
|
||||||
if strings.HasPrefix(strings.ToLower(string(key)), prefix) {
|
|
||||||
keys = append(keys, strings.TrimPrefix(string(key), "/feeds/"))
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
log.WithError(err).Error("error scanning")
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bs *BitcaskStore) GetAllFeeds() ([]*Feed, error) {
|
|
||||||
var feeds []*Feed
|
|
||||||
|
|
||||||
err := bs.db.Scan([]byte(feedsKeyPrefix), func(key []byte) error {
|
|
||||||
data, err := bs.db.Get(key)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
feed, err := LoadFeed(data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
feeds = append(feeds, feed)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return feeds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bs *BitcaskStore) HasUser(username string) bool {
|
func (bs *BitcaskStore) HasUser(username string) bool {
|
||||||
key := []byte(fmt.Sprintf("%s/%s", usersKeyPrefix, username))
|
key := []byte(fmt.Sprintf("%s/%s", usersKeyPrefix, username))
|
||||||
return bs.db.Has(key)
|
return bs.db.Has(key)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package internal
|
|||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/vcraescu/go-paginator"
|
"github.com/vcraescu/go-paginator"
|
||||||
@@ -116,16 +115,5 @@ func NewContext(conf *Config, db Store, req *http.Request) *Context {
|
|||||||
ctx.IsAdmin = true
|
ctx.IsAdmin = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the theme based on user preferences
|
|
||||||
theme := strings.ToLower(ctx.User.Theme)
|
|
||||||
switch theme {
|
|
||||||
case "", "auto":
|
|
||||||
ctx.Theme = ""
|
|
||||||
case "light", "dark":
|
|
||||||
ctx.Theme = theme
|
|
||||||
default:
|
|
||||||
log.WithField("name", theme).Warn("invalid theme found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,18 +28,15 @@ func init() {
|
|||||||
StartupJobs = map[string]JobSpec{}
|
StartupJobs = map[string]JobSpec{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type JobFactory func(conf *Config, blogs *BlogsCache, cache *Cache, archive Archiver, store Store) cron.Job
|
type JobFactory func(conf *Config, store Store) cron.Job
|
||||||
|
|
||||||
type SyncStoreJob struct {
|
type SyncStoreJob struct {
|
||||||
conf *Config
|
conf *Config
|
||||||
blogs *BlogsCache
|
db Store
|
||||||
cache *Cache
|
|
||||||
archive Archiver
|
|
||||||
db Store
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSyncStoreJob(conf *Config, blogs *BlogsCache, cache *Cache, archive Archiver, db Store) cron.Job {
|
func NewSyncStoreJob(conf *Config, db Store) cron.Job {
|
||||||
return &SyncStoreJob{conf: conf, blogs: blogs, cache: cache, archive: archive, db: db}
|
return &SyncStoreJob{conf: conf, db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (job *SyncStoreJob) Run() {
|
func (job *SyncStoreJob) Run() {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package internal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/creasty/defaults"
|
"github.com/creasty/defaults"
|
||||||
@@ -73,12 +71,7 @@ func LoadUser(data []byte) (user *User, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) String() string {
|
func (u *User) String() string {
|
||||||
url, err := url.Parse(u.URL)
|
return u.Username
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Warn("error parsing user url")
|
|
||||||
return u.Username
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s@%s", u.Username, url.Hostname())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasToken will add a token to a user if it doesn't exist already
|
// HasToken will add a token to a user if it doesn't exist already
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package internal
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -174,14 +173,6 @@ func WithAdminEmail(adminEmail string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithFeedSources sets the feed sources to use for external feeds
|
|
||||||
func WithFeedSources(feedSources []string) Option {
|
|
||||||
return func(cfg *Config) error {
|
|
||||||
cfg.FeedSources = feedSources
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithName sets the instance's name
|
// WithName sets the instance's name
|
||||||
func WithName(name string) Option {
|
func WithName(name string) Option {
|
||||||
return func(cfg *Config) error {
|
return func(cfg *Config) error {
|
||||||
@@ -206,14 +197,6 @@ func WithTheme(theme string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithOpenRegistrations sets the open registrations flag
|
|
||||||
func WithOpenRegistrations(openRegistrations bool) Option {
|
|
||||||
return func(cfg *Config) error {
|
|
||||||
cfg.OpenRegistrations = openRegistrations
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCookieSecret sets the server's cookie secret
|
// WithCookieSecret sets the server's cookie secret
|
||||||
func WithCookieSecret(secret string) Option {
|
func WithCookieSecret(secret string) Option {
|
||||||
return func(cfg *Config) error {
|
return func(cfg *Config) error {
|
||||||
@@ -246,14 +229,6 @@ func WithSessionExpiry(expiry time.Duration) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithTranscoderTimeout sets the video transcoding timeout
|
|
||||||
func WithTranscoderTimeout(timeout time.Duration) Option {
|
|
||||||
return func(cfg *Config) error {
|
|
||||||
cfg.TranscoderTimeout = timeout
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMagicLinkSecret sets the MagicLinkSecert used to create password reset tokens
|
// WithMagicLinkSecret sets the MagicLinkSecert used to create password reset tokens
|
||||||
func WithMagicLinkSecret(secret string) Option {
|
func WithMagicLinkSecret(secret string) Option {
|
||||||
return func(cfg *Config) error {
|
return func(cfg *Config) error {
|
||||||
@@ -262,22 +237,6 @@ func WithMagicLinkSecret(secret string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSMTPBind sets the interface and port to bind to for SMTP
|
|
||||||
func WithSMTPBind(smtpBind string) Option {
|
|
||||||
return func(cfg *Config) error {
|
|
||||||
cfg.SMTPBind = smtpBind
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPOP3Bind sets the interface and port to use for POP3
|
|
||||||
func WithPOP3Bind(pop3Bind string) Option {
|
|
||||||
return func(cfg *Config) error {
|
|
||||||
cfg.POP3Bind = pop3Bind
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithSMTPHost sets the SMTPHost to use for sending email
|
// WithSMTPHost sets the SMTPHost to use for sending email
|
||||||
func WithSMTPHost(host string) Option {
|
func WithSMTPHost(host string) Option {
|
||||||
return func(cfg *Config) error {
|
return func(cfg *Config) error {
|
||||||
@@ -318,14 +277,6 @@ func WithSMTPFrom(from string) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithMaxFetchLimit sets the maximum feed fetch limit in bytes
|
|
||||||
func WithMaxFetchLimit(limit int64) Option {
|
|
||||||
return func(cfg *Config) error {
|
|
||||||
cfg.MaxFetchLimit = limit
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAPISessionTime sets the API session time for tokens
|
// WithAPISessionTime sets the API session time for tokens
|
||||||
func WithAPISessionTime(duration time.Duration) Option {
|
func WithAPISessionTime(duration time.Duration) Option {
|
||||||
return func(cfg *Config) error {
|
return func(cfg *Config) error {
|
||||||
@@ -341,17 +292,3 @@ func WithAPISigningKey(key string) Option {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithWhitelistedDomains sets the list of domains whitelisted and permitted for external iamges
|
|
||||||
func WithWhitelistedDomains(whitelistedDomains []string) Option {
|
|
||||||
return func(cfg *Config) error {
|
|
||||||
for _, whitelistedDomain := range whitelistedDomains {
|
|
||||||
re, err := regexp.Compile(whitelistedDomain)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
cfg.whitelistedDomains = append(cfg.whitelistedDomains, re)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -41,27 +41,12 @@ type Server struct {
|
|||||||
router *Router
|
router *Router
|
||||||
server *http.Server
|
server *http.Server
|
||||||
|
|
||||||
// Blogs Cache
|
|
||||||
blogs *BlogsCache
|
|
||||||
|
|
||||||
// Messages Cache
|
|
||||||
msgs *MessagesCache
|
|
||||||
|
|
||||||
// Feed Cache
|
|
||||||
cache *Cache
|
|
||||||
|
|
||||||
// Feed Archiver
|
|
||||||
archive Archiver
|
|
||||||
|
|
||||||
// Data Store
|
// Data Store
|
||||||
db Store
|
db Store
|
||||||
|
|
||||||
// Scheduler
|
// Scheduler
|
||||||
cron *cron.Cron
|
cron *cron.Cron
|
||||||
|
|
||||||
// Dispatcher
|
|
||||||
tasks *Dispatcher
|
|
||||||
|
|
||||||
// Auth
|
// Auth
|
||||||
am *auth.Manager
|
am *auth.Manager
|
||||||
|
|
||||||
@@ -72,21 +57,11 @@ type Server struct {
|
|||||||
// API
|
// API
|
||||||
api *API
|
api *API
|
||||||
|
|
||||||
// POP3 Service
|
|
||||||
pop3Service *POP3Service
|
|
||||||
|
|
||||||
// SMTP Service
|
|
||||||
smtpService *SMTPService
|
|
||||||
|
|
||||||
// Passwords
|
// Passwords
|
||||||
pm passwords.Passwords
|
pm passwords.Passwords
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) render(name string, w http.ResponseWriter, ctx *Context) {
|
func (s *Server) render(name string, w http.ResponseWriter, ctx *Context) {
|
||||||
if ctx.Authenticated && ctx.Username != "" {
|
|
||||||
ctx.NewMessages = s.msgs.Get(ctx.User.Username)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf, err := s.tmplman.Exec(name, ctx)
|
buf, err := s.tmplman.Exec(name, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
@@ -112,8 +87,6 @@ func (s *Server) AddShutdownHook(f func()) {
|
|||||||
// Shutdown ...
|
// Shutdown ...
|
||||||
func (s *Server) Shutdown(ctx context.Context) error {
|
func (s *Server) Shutdown(ctx context.Context) error {
|
||||||
s.cron.Stop()
|
s.cron.Stop()
|
||||||
s.tasks.Stop()
|
|
||||||
s.smtpService.Stop()
|
|
||||||
|
|
||||||
if err := s.server.Shutdown(ctx); err != nil {
|
if err := s.server.Shutdown(ctx); err != nil {
|
||||||
log.WithError(err).Error("error shutting down server")
|
log.WithError(err).Error("error shutting down server")
|
||||||
@@ -190,13 +163,6 @@ func (s *Server) setupMetrics() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// database keys
|
// database keys
|
||||||
metrics.NewGaugeFunc(
|
|
||||||
"db", "feeds",
|
|
||||||
"Number of database /feeds keys",
|
|
||||||
func() float64 {
|
|
||||||
return float64(s.db.LenFeeds())
|
|
||||||
},
|
|
||||||
)
|
|
||||||
metrics.NewGaugeFunc(
|
metrics.NewGaugeFunc(
|
||||||
"db", "sessions",
|
"db", "sessions",
|
||||||
"Number of database /sessions keys",
|
"Number of database /sessions keys",
|
||||||
@@ -264,7 +230,7 @@ func (s *Server) setupCronJobs() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
job := jobSpec.Factory(s.config, s.blogs, s.cache, s.archive, s.db)
|
job := jobSpec.Factory(s.config, s.db)
|
||||||
if err := s.cron.AddJob(jobSpec.Schedule, job); err != nil {
|
if err := s.cron.AddJob(jobSpec.Schedule, job); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -279,7 +245,7 @@ func (s *Server) runStartupJobs() {
|
|||||||
|
|
||||||
log.Info("running startup jobs")
|
log.Info("running startup jobs")
|
||||||
for name, jobSpec := range StartupJobs {
|
for name, jobSpec := range StartupJobs {
|
||||||
job := jobSpec.Factory(s.config, s.blogs, s.cache, s.archive, s.db)
|
job := jobSpec.Factory(s.config, s.db)
|
||||||
log.Infof("running %s now...", name)
|
log.Infof("running %s now...", name)
|
||||||
job.Run()
|
job.Run()
|
||||||
}
|
}
|
||||||
@@ -380,38 +346,6 @@ func NewServer(bind string, options ...Option) (*Server, error) {
|
|||||||
return nil, fmt.Errorf("error validating config: %w", err)
|
return nil, fmt.Errorf("error validating config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
blogs, err := LoadBlogsCache(config.Data)
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Error("error loading blogs cache (re-creating)")
|
|
||||||
blogs = NewBlogsCache()
|
|
||||||
log.Info("updating blogs cache")
|
|
||||||
blogs.UpdateBlogs(config)
|
|
||||||
}
|
|
||||||
if len(blogs.Blogs) == 0 {
|
|
||||||
log.Info("empty blogs cache, updating...")
|
|
||||||
blogs.UpdateBlogs(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
msgs, err := LoadMessagesCache(config.Data)
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Error("error loading messages cache (re-creating)")
|
|
||||||
msgs = NewMessagesCache()
|
|
||||||
}
|
|
||||||
log.Info("updating messages cache")
|
|
||||||
msgs.Refresh(config)
|
|
||||||
|
|
||||||
cache, err := LoadCache(config.Data)
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Error("error loading feed cache")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
archive, err := NewDiskArchiver(filepath.Join(config.Data, archiveDir))
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Error("error creating feed archiver")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := NewStore(config.Store)
|
db, err := NewStore(config.Store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error("error creating store")
|
log.WithError(err).Error("error creating store")
|
||||||
@@ -433,8 +367,6 @@ func NewServer(bind string, options ...Option) (*Server, error) {
|
|||||||
|
|
||||||
am := auth.NewManager(auth.NewOptions("/login", "/register"))
|
am := auth.NewManager(auth.NewOptions("/login", "/register"))
|
||||||
|
|
||||||
tasks := NewDispatcher(10, 100) // TODO: Make this configurable?
|
|
||||||
|
|
||||||
pm := passwords.NewScryptPasswords(nil)
|
pm := passwords.NewScryptPasswords(nil)
|
||||||
|
|
||||||
sc := NewSessionStore(db, config.SessionCacheTTL)
|
sc := NewSessionStore(db, config.SessionCacheTTL)
|
||||||
@@ -449,11 +381,7 @@ func NewServer(bind string, options ...Option) (*Server, error) {
|
|||||||
sc,
|
sc,
|
||||||
)
|
)
|
||||||
|
|
||||||
api := NewAPI(router, config, cache, archive, db, pm, tasks)
|
api := NewAPI(router, config, db, pm)
|
||||||
|
|
||||||
pop3Service := NewPOP3Service(config, db, pm, msgs, tasks)
|
|
||||||
|
|
||||||
smtpService := NewSMTPService(config, db, pm, msgs, tasks)
|
|
||||||
|
|
||||||
csrfHandler := nosurf.New(router)
|
csrfHandler := nosurf.New(router)
|
||||||
csrfHandler.ExemptGlob("/api/v1/*")
|
csrfHandler.ExemptGlob("/api/v1/*")
|
||||||
@@ -479,33 +407,12 @@ func NewServer(bind string, options ...Option) (*Server, error) {
|
|||||||
// API
|
// API
|
||||||
api: api,
|
api: api,
|
||||||
|
|
||||||
// POP3 Servicee
|
|
||||||
pop3Service: pop3Service,
|
|
||||||
|
|
||||||
// SMTP Servicee
|
|
||||||
smtpService: smtpService,
|
|
||||||
|
|
||||||
// Blogs Cache
|
|
||||||
blogs: blogs,
|
|
||||||
|
|
||||||
// Messages Cache
|
|
||||||
msgs: msgs,
|
|
||||||
|
|
||||||
// Feed Cache
|
|
||||||
cache: cache,
|
|
||||||
|
|
||||||
// Feed Archiver
|
|
||||||
archive: archive,
|
|
||||||
|
|
||||||
// Data Store
|
// Data Store
|
||||||
db: db,
|
db: db,
|
||||||
|
|
||||||
// Schedular
|
// Schedular
|
||||||
cron: cron.New(),
|
cron: cron.New(),
|
||||||
|
|
||||||
// Dispatcher
|
|
||||||
tasks: tasks,
|
|
||||||
|
|
||||||
// Auth Manager
|
// Auth Manager
|
||||||
am: am,
|
am: am,
|
||||||
|
|
||||||
@@ -527,12 +434,6 @@ func NewServer(bind string, options ...Option) (*Server, error) {
|
|||||||
server.tasks.Start()
|
server.tasks.Start()
|
||||||
log.Info("started task dispatcher")
|
log.Info("started task dispatcher")
|
||||||
|
|
||||||
server.pop3Service.Start()
|
|
||||||
log.Info("started POP3 service")
|
|
||||||
|
|
||||||
server.smtpService.Start()
|
|
||||||
log.Info("started SMTP service")
|
|
||||||
|
|
||||||
server.setupMetrics()
|
server.setupMetrics()
|
||||||
log.Infof("serving metrics endpoint at %s/metrics", server.config.BaseURL)
|
log.Infof("serving metrics endpoint at %s/metrics", server.config.BaseURL)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ var (
|
|||||||
ErrInvalidStore = errors.New("error: invalid store")
|
ErrInvalidStore = errors.New("error: invalid store")
|
||||||
ErrUserNotFound = errors.New("error: user not found")
|
ErrUserNotFound = errors.New("error: user not found")
|
||||||
ErrTokenNotFound = errors.New("error: token not found")
|
ErrTokenNotFound = errors.New("error: token not found")
|
||||||
ErrFeedNotFound = errors.New("error: feed not found")
|
|
||||||
ErrInvalidSession = errors.New("error: invalid session")
|
ErrInvalidSession = errors.New("error: invalid session")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,14 +19,6 @@ type Store interface {
|
|||||||
Close() error
|
Close() error
|
||||||
Sync() error
|
Sync() error
|
||||||
|
|
||||||
DelFeed(name string) error
|
|
||||||
HasFeed(name string) bool
|
|
||||||
GetFeed(name string) (*Feed, error)
|
|
||||||
SetFeed(name string, user *Feed) error
|
|
||||||
LenFeeds() int64
|
|
||||||
SearchFeeds(prefix string) []string
|
|
||||||
GetAllFeeds() ([]*Feed, error)
|
|
||||||
|
|
||||||
DelUser(username string) error
|
DelUser(username string) error
|
||||||
HasUser(username string) bool
|
HasUser(username string) bool
|
||||||
GetUser(username string) (*User, error)
|
GetUser(username string) (*User, error)
|
||||||
|
|||||||
Reference in New Issue
Block a user