Compare commits

...

13 Commits

4 changed files with 58 additions and 22 deletions

View File

@ -10,4 +10,5 @@ RUN ["mkdir", "-p", "/opt/micropub"]
WORKDIR /opt/micropub WORKDIR /opt/micropub
EXPOSE 80 EXPOSE 80
COPY --from=build-env /go/bin/eksterd /app/ COPY --from=build-env /go/bin/eksterd /app/
COPY --from=build-env /go/bin/ek /app/
ENTRYPOINT ["/app/eksterd"] ENTRYPOINT ["/app/eksterd"]

View File

@ -109,7 +109,10 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
token, err := indieauth.Authorize(me, endpoints) clientID := "https://p83.nl/microsub-client"
scope := "read follow mute block channels"
token, err := indieauth.Authorize(me, endpoints, clientID, scope)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -145,6 +148,8 @@ func performCommands(sub microsub.Microsub, commands []string) {
Commands: Commands:
connect URL login to Indieauth url
channels list channels channels list channels
channels NAME create channel with NAME channels NAME create channel with NAME
channels UID NAME update channel UID with NAME channels UID NAME update channel UID with NAME
@ -253,7 +258,10 @@ Commands:
} }
func showItem(item *microsub.Item) { func showItem(item *microsub.Item) {
fmt.Printf("%s - %s - %s\n", item.Name, item.Published, item.ID) if item.Name != "" {
fmt.Printf("%s - ", item.Name)
}
fmt.Printf("%s\n", item.Published)
if item.Content != nil { if item.Content != nil {
if item.Content.Text != "" { if item.Content.Text != "" {
fmt.Println(item.Content.Text) fmt.Println(item.Content.Text)

View File

@ -121,20 +121,19 @@ func createMemoryBackend() microsub.Microsub {
backend.Channels = make(map[string]microsub.Channel) backend.Channels = make(map[string]microsub.Channel)
backend.Feeds = make(map[string][]microsub.Feed) backend.Feeds = make(map[string][]microsub.Feed)
channels := []microsub.Channel{ channels := []microsub.Channel{
microsub.Channel{UID: "0000", Name: "default"}, microsub.Channel{UID: "notifications", Name: "Notifications"},
microsub.Channel{UID: "0001", Name: "notifications"}, microsub.Channel{UID: "home", Name: "Home"},
microsub.Channel{UID: "1000", Name: "Friends"},
microsub.Channel{UID: "1001", Name: "Family"},
} }
for _, c := range channels { for _, c := range channels {
backend.Channels[c.UID] = c backend.Channels[c.UID] = c
} }
backend.NextUid = 1002 backend.NextUid = 1000000
backend.Me = "https://example.com/" backend.Me = "https://example.com/"
log.Println(`Config file "backend.json" is created in the current directory.`) log.Println(`Config file "backend.json" is created in the current directory.`)
log.Println(`Update "Me" variable to your website address "https://example.com/"`) log.Println(`Update "Me" variable to your website address "https://example.com/"`)
log.Println(`Update "TokenEndpoint" variable to the address of your token endpoint "https://example.com/token"`)
return &backend return &backend
} }
@ -152,7 +151,9 @@ func (b *memoryBackend) ChannelsGetList() []microsub.Channel {
} }
} else { } else {
for _, uid := range uids { for _, uid := range uids {
channels = append(channels, b.Channels[uid]) if c, e := b.Channels[uid]; e {
channels = append(channels, c)
}
} }
} }
return channels return channels
@ -188,13 +189,14 @@ func (b *memoryBackend) ChannelsUpdate(uid, name string) microsub.Channel {
func (b *memoryBackend) ChannelsDelete(uid string) { func (b *memoryBackend) ChannelsDelete(uid string) {
defer b.save() defer b.save()
if _, e := b.Channels[uid]; e { conn := pool.Get()
delete(b.Channels, uid) defer conn.Close()
}
if _, e := b.Feeds[uid]; e { conn.Do("SREM", "channels", uid)
delete(b.Feeds, uid) conn.Do("DEL", "channel_sortorder_"+uid)
}
delete(b.Channels, uid)
delete(b.Feeds, uid)
} }
func mapToAuthor(result map[string]string) *microsub.Card { func mapToAuthor(result map[string]string) *microsub.Card {
@ -722,6 +724,9 @@ func (b *memoryBackend) MarkRead(channel string, uids []string) {
unread -= len(uids) unread -= len(uids)
if ch, e := b.Channels[channel]; e { if ch, e := b.Channels[channel]; e {
if unread < 0 {
unread = 0
}
ch.Unread = unread ch.Unread = unread
b.Channels[channel] = ch b.Channels[channel] = ch
} }

View File

@ -9,6 +9,9 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"linkheader"
"github.com/pstuifzand/ekster/pkg/util"
"willnorris.com/go/microformats" "willnorris.com/go/microformats"
) )
@ -37,25 +40,44 @@ func GetEndpoints(me *url.URL) (Endpoints, error) {
} }
defer res.Body.Close() defer res.Body.Close()
var links linkheader.Links
if headers, e := res.Header["Link"]; e {
links = linkheader.ParseMultiple(headers)
for _, link := range links {
if link.Rel == "authorization_endpoint" {
endpoints.AuthorizationEndpoint = link.URL
} else if link.Rel == "token_endpoint" {
endpoints.TokenEndpoint = link.URL
} else if link.Rel == "micropub" {
endpoints.MicropubEndpoint = link.URL
} else if link.Rel == "microsub" {
endpoints.MicrosubEndpoint = link.URL
} else {
log.Printf("Skipping unsupported rels in Link header: %s %s\n", link.Rel, link.URL)
}
}
}
data := microformats.Parse(res.Body, baseURL) data := microformats.Parse(res.Body, baseURL)
if auth, e := data.Rels["authorization_endpoint"]; e { if auth, e := data.Rels["authorization_endpoint"]; e && endpoints.AuthorizationEndpoint == "" {
endpoints.AuthorizationEndpoint = auth[0] endpoints.AuthorizationEndpoint = auth[0]
} }
if token, e := data.Rels["token_endpoint"]; e { if token, e := data.Rels["token_endpoint"]; e && endpoints.TokenEndpoint == "" {
endpoints.TokenEndpoint = token[0] endpoints.TokenEndpoint = token[0]
} }
if micropub, e := data.Rels["micropub"]; e { if micropub, e := data.Rels["micropub"]; e && endpoints.MicropubEndpoint == "" {
endpoints.MicropubEndpoint = micropub[0] endpoints.MicropubEndpoint = micropub[0]
} }
if microsub, e := data.Rels["microsub"]; e { if microsub, e := data.Rels["microsub"]; e && endpoints.MicrosubEndpoint == "" {
endpoints.MicrosubEndpoint = microsub[0] endpoints.MicrosubEndpoint = microsub[0]
} }
return endpoints, nil return endpoints, nil
} }
func Authorize(me *url.URL, endpoints Endpoints) (TokenResponse, error) { func Authorize(me *url.URL, endpoints Endpoints, clientID, scope string) (TokenResponse, error) {
var tokenResponse TokenResponse var tokenResponse TokenResponse
authURL, err := url.Parse(endpoints.AuthorizationEndpoint) authURL, err := url.Parse(endpoints.AuthorizationEndpoint)
@ -68,10 +90,9 @@ func Authorize(me *url.URL, endpoints Endpoints) (TokenResponse, error) {
return tokenResponse, err return tokenResponse, err
} }
clientID := "https://p83.nl/microsub-client"
local := ln.Addr().String() local := ln.Addr().String()
redirectURI := fmt.Sprintf("http://%s/", local) redirectURI := fmt.Sprintf("http://%s/", local)
state := "12345344" state := util.RandStringBytes(16)
q := authURL.Query() q := authURL.Query()
q.Add("response_type", "code") q.Add("response_type", "code")
@ -79,7 +100,7 @@ func Authorize(me *url.URL, endpoints Endpoints) (TokenResponse, error) {
q.Add("client_id", clientID) q.Add("client_id", clientID)
q.Add("redirect_uri", redirectURI) q.Add("redirect_uri", redirectURI)
q.Add("state", state) q.Add("state", state)
q.Add("scope", "read follow mute block channels") q.Add("scope", scope)
authURL.RawQuery = q.Encode() authURL.RawQuery = q.Encode()
log.Printf("Browse to %s\n", authURL.String()) log.Printf("Browse to %s\n", authURL.String())
@ -94,6 +115,7 @@ func Authorize(me *url.URL, endpoints Endpoints) (TokenResponse, error) {
if state != responseState { if state != responseState {
log.Println("Wrong state response") log.Println("Wrong state response")
} }
fmt.Fprintf(w, `<div style="width:100%%;height:100%%;display: flex; align-items: center; justify-content: center;">You can close this window, proceed on the command line</div>`)
close(shutdown) close(shutdown)
} }