Skip to content

Commit

Permalink
10 add file content type (#14)
Browse files Browse the repository at this point in the history
* new: add files upload
* new: ` /api/secrets` endpoint dumps all feed names and secrets to console
* fix: refactor PIN modal and input
* Major refactor and updates
  • Loading branch information
ybizeul authored Oct 14, 2024
1 parent ef5432e commit ce31638
Show file tree
Hide file tree
Showing 42 changed files with 10,693 additions and 4,562 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/push-container-dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
on:
push:
branches-ignore:
- main

jobs:
release:
name: release
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
# Checkout code
- uses: actions/checkout@v3
with:
fetch-depth: 0

# Fetch tags
- run: git fetch --force --tags

# Set version environment
- name: Set VERSION
run: |
echo "YBFEED_VERSION=`git describe --tags`" >> $GITHUB_ENV
# Build web ui
- name: Use Node.js 22.x
uses: actions/setup-node@v3
with:
node-version: 22.x
- run: corepack enable
working-directory: ./web/ui
- run: yarn
working-directory: ./web/ui
- run: yarn build
working-directory: ./web/ui

# Build docker image
- uses: ko-build/[email protected]
- run: GOFLAGS="-ldflags=-X=main.version=$YBFEED_VERSION" ko build -B --platform all --tags dev --sbom none ./cmd/ybfeed
env:
KO_DOCKER_REPO: ghcr.io/ybizeul
10 changes: 6 additions & 4 deletions .github/workflows/push-container.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ jobs:
echo "YBFEED_VERSION=`git describe --tags`" >> $GITHUB_ENV
# Build web ui
- name: Use Node.js 20.x
- name: Use Node.js 22.x
uses: actions/setup-node@v3
with:
node-version: 20.x
- run: npm install
node-version: 22.x
- run: corepack enable
working-directory: ./web/ui
- run: npm run build
- run: yarn
working-directory: ./web/ui
- run: yarn build
working-directory: ./web/ui

# Build docker image
Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ jobs:
echo "YBFEED_VERSION=`git describe --tags`" >> $GITHUB_ENV
# Build web ui
- name: Use Node.js 20.x
- name: Use Node.js 22.x
uses: actions/setup-node@v3
with:
node-version: 20.x
- run: npm install
node-version: 22.x
- run: corepack enable
working-directory: ./web/ui
- run: npm run build
- run: yarn
working-directory: ./web/ui
- run: yarn build
working-directory: ./web/ui


# Build go binary
- uses: actions/setup-go@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ web/ui/build/
/ybFeed
dist/
.vscode
__debug*
Binary file removed cmd/ybfeed/__debug_bin2036534813
Binary file not shown.
31 changes: 23 additions & 8 deletions internal/feed/feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,19 @@ func (feed *Feed) Empty() error {
return err
}
for _, item := range items {
err := feed.RemoveItem(item.Name)
err := feed.RemoveItem(item.Name, false)
if err != nil {
return err
}
}

// Notify all connected websockets
if feed.WebSocketManager != nil {
if err = feed.WebSocketManager.NotifyEmpty(feed); err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -332,7 +340,7 @@ func (feed *Feed) IsSecretValid(secret string) error {

// AddItem reads content from r and creates a new file in the feed directory
// with a name and file extension based on contentType, then notifies clients
func (f *Feed) AddItem(contentType string, r io.Reader) error {
func (f *Feed) AddItem(contentType string, filename string, r io.Reader) error {
fL.Logger.Debug("Adding Item", slog.String("feed", f.Name()), slog.String("content-type", contentType))

var err error
Expand All @@ -347,7 +355,11 @@ func (f *Feed) AddItem(contentType string, r io.Reader) error {
// If the content-type isn't found, return an error
info, ok := mimeInfos[contentType]
if !ok {
return fmt.Errorf("%w: %s", FeedErrorInvalidContentType, contentType)
info = FileTypeInfo{
FileExtension: path.Ext(filename)[1:],
FileNameTemplate: filename[:len(filename)-len(path.Ext(filename))],
}
//return fmt.Errorf("%w: %s", FeedErrorInvalidContentType, contentType)
}

// Obtain file extension and template for file name
Expand All @@ -371,10 +383,13 @@ func (f *Feed) AddItem(contentType string, r io.Reader) error {

// Search for existing content with identical file type to increment
// the index in file name
fileIndex := 1
var filename string
fileIndex := 0
for {
filename = fmt.Sprintf("%s %d", template, fileIndex)
fileIndexStr := ""
if fileIndex > 0 {
fileIndexStr = fmt.Sprintf(" %d", fileIndex)
}
filename = fmt.Sprintf("%s%s", template, fileIndexStr)
matches, err := filepath.Glob(path.Join(f.Path, filename) + ".*")
if err != nil {
return fmt.Errorf("%w: %s", FeedErrorErrorReading, filename)
Expand Down Expand Up @@ -420,7 +435,7 @@ func (f *Feed) AddItem(contentType string, r io.Reader) error {
}

// RemoveItem deletes item from the feed directory and notifies clients
func (f *Feed) RemoveItem(item string) error {
func (f *Feed) RemoveItem(item string, notify bool) error {
fL.Logger.Debug("Remove Item", slog.String("name", item), slog.String("feed", f.Path))

itemPath := path.Join(f.Path, path.Join("/", item))
Expand All @@ -441,7 +456,7 @@ func (f *Feed) RemoveItem(item string) error {
}

// Notify all connected websockets
if f.WebSocketManager != nil {
if f.WebSocketManager != nil && notify {
if err = f.WebSocketManager.NotifyRemove(publicItem); err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions internal/feed/feed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestGetFeedItemData(t *testing.T) {

reader := bytes.NewReader([]byte("test"))

err = f.AddItem("text/plain", reader)
err = f.AddItem("text/plain", "", reader)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -70,7 +70,7 @@ func TestPathTraversalDelete(t *testing.T) {
t.Fatal(err)
}

err = f.RemoveItem("../feed1/config.json")
err = f.RemoveItem("../feed1/config.json", true)

if err == nil {
t.Fatal("Path traversal not blocked")
Expand Down Expand Up @@ -110,7 +110,7 @@ func TestPublicItem(t *testing.T) {

reader := bytes.NewReader([]byte("test"))

err = f.AddItem("text/plain", reader)
err = f.AddItem("text/plain", "", reader)
if err != nil {
t.Fatal(err)
}
Expand Down
22 changes: 22 additions & 0 deletions internal/feed/feedmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package feed

import (
"fmt"
"os"
"path"
)

Expand Down Expand Up @@ -60,3 +61,24 @@ func (m *FeedManager) GetFeedWithAuth(feedName string, secret string) (*Feed, er

return result, nil
}

func (m *FeedManager) DumpSecrets() {
d, err := os.ReadDir(m.path)
if err != nil {
// TODO: log error
return
}
for _, entry := range d {
if !entry.IsDir() {
continue
}
feedPath := path.Join(m.path, entry.Name())

result, err := GetFeed(feedPath)
if err != nil {
// TODO Log error
return
}
fmt.Printf("Feed %s: %s\n", result.Name(), result.Config.Secret)
}
}
8 changes: 6 additions & 2 deletions internal/feed/pushnotifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,21 @@ func (f *Feed) sendPushNotification() error {
// For each subscription we send the notification
for _, subscription := range f.Config.Subscriptions {
pnL.Logger.Debug("Sending push notification", slog.String("endpoint", subscription.Endpoint))
resp, _ := webpush.SendNotification([]byte(fmt.Sprintf("New item posted to feed %s", f.Name())), &subscription, &webpush.Options{
resp, err := webpush.SendNotification([]byte(fmt.Sprintf("New item posted to feed %s", f.Name())), &subscription, &webpush.Options{
Subscriber: "[email protected]", // Do not include "mailto:"
VAPIDPublicKey: f.NotificationSettings.VAPIDPublicKey,
VAPIDPrivateKey: f.NotificationSettings.VAPIDPrivateKey,
TTL: 30,
})
if err != nil {
pnL.Logger.Error("Sending push notification failed:", slog.String("error", err.Error()))
continue
}
if pnL.Level() == slog.LevelDebug {
b, _ := io.ReadAll(resp.Body)
pnL.Logger.Debug("Response", slog.String("resp", string(b)), slog.String("status", resp.Status))
}
defer resp.Body.Close()
//defer resp.Body.Close()
}
return nil
}
19 changes: 19 additions & 0 deletions internal/feed/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,22 @@ func (m *WebSocketManager) NotifyRemove(item *PublicFeedItem) error {
}
return nil
}

func (m *WebSocketManager) NotifyEmpty(feed *Feed) error {
wsL.Logger.Debug("Notify websocket empty",
slog.Int("ws count", len(m.FeedSockets)))
for _, f := range m.FeedSockets {
wsL.Logger.Debug("checking feed", slog.String("feedName", f.feedName))
if f.feedName == feed.Name() {
wsL.Logger.Debug("found feed", slog.String("feedName", f.feedName))
for _, w := range f.websockets {
if err := w.WriteJSON(FeedNotification{
Action: "empty",
}); err != nil {
return err
}
}
}
}
return nil
}
Loading

0 comments on commit ce31638

Please sign in to comment.