diff --git a/cmd/owl/web/auth_test.go b/cmd/owl/web/auth_test.go
index 9ce37f9..844b598 100644
--- a/cmd/owl/web/auth_test.go
+++ b/cmd/owl/web/auth_test.go
@@ -399,3 +399,29 @@ func TestAccessTokenWithIncorrectCode(t *testing.T) {
assertions.AssertStatus(t, rr, http.StatusUnauthorized)
}
+
+func TestIndieauthMetadata(t *testing.T) {
+ repo, user := getSingleUserTestRepo()
+ user.ResetPassword("testpassword")
+ req, _ := http.NewRequest("GET", user.IndieauthMetadataUrl(), nil)
+ rr := httptest.NewRecorder()
+ router := main.SingleUserRouter(&repo)
+ router.ServeHTTP(rr, req)
+
+ assertions.AssertStatus(t, rr, http.StatusOK)
+ // parse response as json
+ type responseType struct {
+ Issuer string `json:"issuer"`
+ AuthorizationEndpoint string `json:"authorization_endpoint"`
+ TokenEndpoint string `json:"token_endpoint"`
+ CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
+ ScopesSupported []string `json:"scopes_supported"`
+ ResponseTypesSupported []string `json:"response_types_supported"`
+ GrantTypesSupported []string `json:"grant_types_supported"`
+ }
+ var response responseType
+ json.Unmarshal(rr.Body.Bytes(), &response)
+ assertions.AssertEqual(t, response.Issuer, user.FullUrl())
+ assertions.AssertEqual(t, response.AuthorizationEndpoint, user.AuthUrl())
+ assertions.AssertEqual(t, response.TokenEndpoint, user.TokenUrl())
+}
diff --git a/cmd/owl/web/handler.go b/cmd/owl/web/handler.go
index 4cbf887..0bf1d22 100644
--- a/cmd/owl/web/handler.go
+++ b/cmd/owl/web/handler.go
@@ -60,6 +60,43 @@ func userIndexHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Requ
}
}
+func userAuthMetadataHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
+ return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
+ user, err := getUserFromRepo(repo, ps)
+ if err != nil {
+ println("Error getting user: ", err.Error())
+ notFoundHandler(repo)(w, r)
+ return
+ }
+
+ type Response struct {
+ Issuer string `json:"issuer"`
+ AuthorizationEndpoint string `json:"authorization_endpoint"`
+ TokenEndpoint string `json:"token_endpoint"`
+ CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
+ ScopesSupported []string `json:"scopes_supported"`
+ ResponseTypesSupported []string `json:"response_types_supported"`
+ GrantTypesSupported []string `json:"grant_types_supported"`
+ }
+ response := Response{
+ Issuer: user.FullUrl(),
+ AuthorizationEndpoint: user.AuthUrl(),
+ TokenEndpoint: user.TokenUrl(),
+ CodeChallengeMethodsSupported: []string{"S256", "plain"},
+ ScopesSupported: []string{"profile"},
+ ResponseTypesSupported: []string{"code"},
+ GrantTypesSupported: []string{"authorization_code"},
+ }
+ jsonData, err := json.Marshal(response)
+ if err != nil {
+ println("Error marshalling json: ", err.Error())
+ w.WriteHeader(http.StatusInternalServerError)
+ w.Write([]byte("Internal server error"))
+ }
+ w.Write(jsonData)
+ }
+}
+
func userAuthHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
user, err := getUserFromRepo(repo, ps)
diff --git a/cmd/owl/web/server.go b/cmd/owl/web/server.go
index 02937c1..7e75ac5 100644
--- a/cmd/owl/web/server.go
+++ b/cmd/owl/web/server.go
@@ -18,6 +18,7 @@ func Router(repo *owl.Repository) http.Handler {
router.POST("/user/:user/auth/", userAuthProfileHandler(repo))
router.POST("/user/:user/auth/verify/", userAuthVerifyHandler(repo))
router.POST("/user/:user/auth/token/", userAuthTokenHandler(repo))
+ router.GET("/user/:user/auth/indieauth-metadata", userAuthMetadataHandler(repo))
router.GET("/user/:user/media/*filepath", userMediaHandler(repo))
router.GET("/user/:user/index.xml", userRSSHandler(repo))
router.GET("/user/:user/posts/:post/", postHandler(repo))
@@ -35,6 +36,7 @@ func SingleUserRouter(repo *owl.Repository) http.Handler {
router.POST("/auth/", userAuthProfileHandler(repo))
router.POST("/auth/verify/", userAuthVerifyHandler(repo))
router.POST("/auth/token/", userAuthTokenHandler(repo))
+ router.GET("/auth/indieauth-metadata", userAuthMetadataHandler(repo))
router.GET("/media/*filepath", userMediaHandler(repo))
router.GET("/index.xml", userRSSHandler(repo))
router.GET("/posts/:post/", postHandler(repo))
diff --git a/embed/initial/base.html b/embed/initial/base.html
index ff99bb4..78ad250 100644
--- a/embed/initial/base.html
+++ b/embed/initial/base.html
@@ -28,6 +28,7 @@
{{ if .User.AuthUrl }}
+
{{ end }}
diff --git a/user.go b/user.go
index ec0b2c3..6d1200a 100644
--- a/user.go
+++ b/user.go
@@ -78,6 +78,11 @@ func (user User) TokenUrl() string {
return url
}
+func (user User) IndieauthMetadataUrl() string {
+ url, _ := url.JoinPath(user.AuthUrl(), "indieauth-metadata")
+ return url
+}
+
func (user User) WebmentionUrl() string {
url, _ := url.JoinPath(user.FullUrl(), "webmention/")
return url