113 lines
2.8 KiB
Go
113 lines
2.8 KiB
Go
package middleware
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
|
|
"github.com/labstack/echo/v5"
|
|
"github.com/pocketbase/pocketbase"
|
|
"github.com/pocketbase/pocketbase/apis"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
"github.com/pocketbase/pocketbase/tokens"
|
|
"github.com/pocketbase/pocketbase/tools/security"
|
|
"github.com/spf13/cast"
|
|
)
|
|
|
|
const AuthCookieName = "Auth"
|
|
|
|
func AddCookieSessionMiddleware(app *pocketbase.PocketBase, isTlsEnabled bool) {
|
|
log.Println("Warning: starting server with cookie Secure = false!")
|
|
|
|
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
|
e.Router.Use(loadAuthContextFromCookie(app))
|
|
return nil
|
|
})
|
|
|
|
// fires for every auth collection
|
|
app.OnRecordAuthRequest().Add(func(e *core.RecordAuthEvent) error {
|
|
e.HttpContext.SetCookie(&http.Cookie{
|
|
Name: AuthCookieName,
|
|
Value: e.Token,
|
|
Path: "/",
|
|
Secure: isTlsEnabled,
|
|
HttpOnly: true,
|
|
})
|
|
e.HttpContext.SetCookie(&http.Cookie{
|
|
Name: "username",
|
|
Value: e.Record.Username(),
|
|
})
|
|
return nil
|
|
})
|
|
app.OnAdminAuthRequest().Add(func(e *core.AdminAuthEvent) error {
|
|
e.HttpContext.SetCookie(&http.Cookie{
|
|
Name: AuthCookieName,
|
|
Value: e.Token,
|
|
Path: "/",
|
|
Secure: isTlsEnabled,
|
|
HttpOnly: true,
|
|
})
|
|
return nil
|
|
})
|
|
app.OnBeforeServe().Add(getLogoutRoute(app, isTlsEnabled))
|
|
}
|
|
|
|
func loadAuthContextFromCookie(app core.App) echo.MiddlewareFunc {
|
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
tokenCookie, err := c.Request().Cookie(AuthCookieName)
|
|
if err != nil || tokenCookie.Value == "" {
|
|
return next(c) // no token cookie
|
|
}
|
|
|
|
token := tokenCookie.Value
|
|
|
|
claims, _ := security.ParseUnverifiedJWT(token)
|
|
tokenType := cast.ToString(claims["type"])
|
|
|
|
switch tokenType {
|
|
case tokens.TypeAdmin:
|
|
admin, err := app.Dao().FindAdminByToken(
|
|
token,
|
|
app.Settings().AdminAuthToken.Secret,
|
|
)
|
|
if err == nil && admin != nil {
|
|
// "authenticate" the admin
|
|
c.Set(apis.ContextAdminKey, admin)
|
|
}
|
|
|
|
case tokens.TypeAuthRecord:
|
|
record, err := app.Dao().FindAuthRecordByToken(
|
|
token,
|
|
app.Settings().RecordAuthToken.Secret,
|
|
)
|
|
if err == nil && record != nil {
|
|
// "authenticate" the app user
|
|
c.Set(apis.ContextAuthRecordKey, record)
|
|
}
|
|
}
|
|
|
|
return next(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
// render and return login page with configured oauth providers
|
|
func getLogoutRoute(app *pocketbase.PocketBase, isTlsEnabled bool) func(*core.ServeEvent) error {
|
|
return func (e *core.ServeEvent) error {
|
|
e.Router.GET("/logout", func(c echo.Context) error {
|
|
c.SetCookie(&http.Cookie{
|
|
Name: AuthCookieName,
|
|
Value: "",
|
|
Path: "/",
|
|
MaxAge: -1,
|
|
Secure: isTlsEnabled,
|
|
HttpOnly: true,
|
|
})
|
|
c.Response().Header().Add("HX-Trigger", "auth-change-event")
|
|
return c.JSON(http.StatusOK, map[string]string{"message": "session cookie removed"})
|
|
})
|
|
return nil
|
|
}
|
|
}
|
|
|