fixed twitch authentication

This commit is contained in:
2025-08-25 12:48:30 +02:00
parent 4e1b4bad0a
commit 4f8510bac8
7 changed files with 61 additions and 16 deletions

1
.gitignore vendored
View File

@@ -29,3 +29,4 @@ frontend/.yarn/install-state.gz
livestreams.dat livestreams.dat
.vite/deps .vite/deps
archive.txt archive.txt
twitch-monitor.dat

View File

@@ -4,6 +4,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
"time"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@@ -34,6 +35,7 @@ type Config struct {
Twitch struct { Twitch struct {
ClientId string `yaml:"client_id"` ClientId string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"` ClientSecret string `yaml:"client_secret"`
CheckInterval time.Duration `yaml:"check_interval"`
} `yaml:"twitch"` } `yaml:"twitch"`
} }

View File

@@ -0,0 +1,20 @@
package middlewares
import (
"net/http"
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/config"
"github.com/marcopiovanello/yt-dlp-web-ui/v3/server/openid"
)
func ApplyAuthenticationByConfig(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if config.Instance().RequireAuth {
Authenticated(next)
}
if config.Instance().UseOpenId {
openid.Middleware(next)
}
next.ServeHTTP(w, r)
})
}

View File

@@ -123,10 +123,14 @@ func RunBlocking(rc *RunConfig) {
config.Instance().Twitch.ClientSecret, config.Instance().Twitch.ClientSecret,
), ),
) )
go tm.Monitor(context.TODO(), time.Minute*1, twitch.DEFAULT_DOWNLOAD_HANDLER(mdb, mq)) go tm.Monitor(
context.TODO(),
config.Instance().Twitch.CheckInterval,
twitch.DEFAULT_DOWNLOAD_HANDLER(mdb, mq),
)
go tm.Restore() go tm.Restore()
srv := newServer(serverConfig{ scfg := serverConfig{
frontend: rc.App, frontend: rc.App,
swagger: rc.Swagger, swagger: rc.Swagger,
mdb: mdb, mdb: mdb,
@@ -134,9 +138,11 @@ func RunBlocking(rc *RunConfig) {
db: db, db: db,
lm: lm, lm: lm,
tm: tm, tm: tm,
}) }
go gracefulShutdown(srv, mdb) srv := newServer(scfg)
go gracefulShutdown(srv, &scfg)
go autoPersist(time.Minute*5, mdb, lm, tm) go autoPersist(time.Minute*5, mdb, lm, tm)
var ( var (
@@ -200,12 +206,7 @@ func newServer(c serverConfig) *http.Server {
// Filebrowser routes // Filebrowser routes
r.Route("/filebrowser", func(r chi.Router) { r.Route("/filebrowser", func(r chi.Router) {
if config.Instance().RequireAuth { r.Use(middlewares.ApplyAuthenticationByConfig)
r.Use(middlewares.Authenticated)
}
if config.Instance().UseOpenId {
r.Use(openid.Middleware)
}
r.Post("/downloaded", filebrowser.ListDownloaded) r.Post("/downloaded", filebrowser.ListDownloaded)
r.Post("/delete", filebrowser.DeleteFile) r.Post("/delete", filebrowser.DeleteFile)
r.Get("/d/{id}", filebrowser.DownloadFile) r.Get("/d/{id}", filebrowser.DownloadFile)
@@ -249,13 +250,15 @@ func newServer(c serverConfig) *http.Server {
// Twitch // Twitch
r.Route("/twitch", func(r chi.Router) { r.Route("/twitch", func(r chi.Router) {
r.Use(middlewares.ApplyAuthenticationByConfig)
r.Get("/all", twitch.GetMonitoredUsers(c.tm))
r.Post("/add", twitch.MonitorUserHandler(c.tm)) r.Post("/add", twitch.MonitorUserHandler(c.tm))
}) })
return &http.Server{Handler: r} return &http.Server{Handler: r}
} }
func gracefulShutdown(srv *http.Server, db *internal.MemoryDB) { func gracefulShutdown(srv *http.Server, cfg *serverConfig) {
ctx, stop := signal.NotifyContext(context.Background(), ctx, stop := signal.NotifyContext(context.Background(),
os.Interrupt, os.Interrupt,
syscall.SIGTERM, syscall.SIGTERM,
@@ -267,7 +270,9 @@ func gracefulShutdown(srv *http.Server, db *internal.MemoryDB) {
slog.Info("shutdown signal received") slog.Info("shutdown signal received")
defer func() { defer func() {
db.Persist() cfg.mdb.Persist()
cfg.lm.Persist()
cfg.tm.Persist()
stop() stop()
srv.Shutdown(context.Background()) srv.Shutdown(context.Background())
@@ -282,6 +287,7 @@ func autoPersist(
tm *twitch.Monitor, tm *twitch.Monitor,
) { ) {
for { for {
time.Sleep(d)
if err := db.Persist(); err != nil { if err := db.Persist(); err != nil {
slog.Warn("failed to persisted session", slog.Any("err", err)) slog.Warn("failed to persisted session", slog.Any("err", err))
} }
@@ -294,6 +300,5 @@ func autoPersist(
"failed to persisted twitch monitor session", slog.Any("err", err.Error())) "failed to persisted twitch monitor session", slog.Any("err", err.Error()))
} }
slog.Debug("sucessfully persisted session") slog.Debug("sucessfully persisted session")
time.Sleep(d)
} }
} }

View File

@@ -36,7 +36,7 @@ func NewAuthenticationManager(clientId, clientSecret string) *AuthenticationMana
} }
func (a *AuthenticationManager) GetAccessToken() (*AccessToken, error) { func (a *AuthenticationManager) GetAccessToken() (*AccessToken, error) {
if a.accesToken != nil && a.accesToken.Expiry.After(time.Now()) { if a.accesToken != nil && a.accesToken.Token != "" && a.accesToken.Expiry.After(time.Now()) {
return a.accesToken, nil return a.accesToken, nil
} }

View File

@@ -70,6 +70,11 @@ func (c *Client) PollStream(channel string, liveChannel chan<- *StreamInfo) erro
return err return err
} }
if len(sr.Data) == 0 {
liveChannel <- &StreamInfo{UserName: channel, IsLive: false}
return nil
}
s := sr.Data[0] s := sr.Data[0]
started, _ := time.Parse(time.RFC3339, s.StartedAt) started, _ := time.Parse(time.RFC3339, s.StartedAt)

View File

@@ -3,6 +3,7 @@ package twitch
import ( import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"slices"
) )
type addUserReq struct { type addUserReq struct {
@@ -26,3 +27,14 @@ func MonitorUserHandler(m *Monitor) http.HandlerFunc {
} }
} }
} }
func GetMonitoredUsers(m *Monitor) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
it := m.GetMonitoredUsers()
if err := json.NewEncoder(w).Encode(slices.Collect(it)); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
}