apis

package
v0.23.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2024 License: MIT Imports: 60 Imported by: 219

Documentation

Index

Constants

View Source
const (
	DefaultWWWRedirectMiddlewarePriority = -99999
	DefaultWWWRedirectMiddlewareId       = "pbWWWRedirect"

	DefaultActivityLoggerMiddlewarePriority   = DefaultRateLimitMiddlewarePriority - 40
	DefaultActivityLoggerMiddlewareId         = "pbActivityLogger"
	DefaultSkipSuccessActivityLogMiddlewareId = "pbSkipSuccessActivityLog"
	DefaultEnableAuthIdActivityLog            = "pbEnableAuthIdActivityLog"

	DefaultPanicRecoverMiddlewarePriority = DefaultRateLimitMiddlewarePriority - 30
	DefaultPanicRecoverMiddlewareId       = "pbPanicRecover"

	DefaultLoadAuthTokenMiddlewarePriority = DefaultRateLimitMiddlewarePriority - 20
	DefaultLoadAuthTokenMiddlewareId       = "pbLoadAuthToken"

	DefaultSecurityHeadersMiddlewarePriority = DefaultRateLimitMiddlewarePriority - 10
	DefaultSecurityHeadersMiddlewareId       = "pbSecurityHeaders"

	DefaultRequireGuestOnlyMiddlewareId                 = "pbRequireGuestOnly"
	DefaultRequireAuthMiddlewareId                      = "pbRequireAuth"
	DefaultRequireSuperuserAuthMiddlewareId             = "pbRequireSuperuserAuth"
	DefaultRequireSuperuserOrOwnerAuthMiddlewareId      = "pbRequireSuperuserOrOwnerAuth"
	DefaultRequireSameCollectionContextAuthMiddlewareId = "pbRequireSameCollectionContextAuth"
)
View Source
const (
	DefaultBodyLimitMiddlewareId       = "pbBodyLimit"
	DefaultBodyLimitMiddlewarePriority = DefaultRateLimitMiddlewarePriority + 10
)
View Source
const (
	DefaultCorsMiddlewareId       = "pbCors"
	DefaultCorsMiddlewarePriority = DefaultActivityLoggerMiddlewarePriority - 1 // before the activity logger and rate limit so that OPTIONS preflight requests are not counted
)
View Source
const (
	DefaultRateLimitMiddlewareId       = "pbRateLimit"
	DefaultRateLimitMiddlewarePriority = -1000
)
View Source
const (
	DefaultGzipMiddlewareId = "pbGzip"
)
View Source
const DefaultMaxBodySize int64 = 32 << 20
View Source
const RealtimeClientAuthKey = "auth"

RealtimeClientAuthKey is the name of the realtime client store key that holds its auth state.

View Source
const (
	RequestEventKeyLogMeta = "pbLogMeta" // extra data to store with the request activity log

)

Common request event store keys used by the middlewares and api handlers.

View Source
const StaticWildcardParam = "path"

StaticWildcardParam is the name of Static handler wildcard parameter.

Variables

View Source
var DefaultCORSConfig = CORSConfig{
	AllowOrigins: []string{"*"},
	AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete},
}

DefaultCORSConfig is the default CORS middleware config.

View Source
var ErrMFA = errors.New("mfa required")
View Source
var ErrRequestEntityTooLarge = router.NewApiError(http.StatusRequestEntityTooLarge, "Request entity too large", nil)
View Source
var ValidBatchActions = map[*regexp.Regexp]BatchActionHandlerFunc{

	regexp.MustCompile(`^PUT /api/collections/(?P<collection>[^\/\?]+)/records(?P<query>\?.*)?$`): func(app core.App, ir *core.InternalRequest, params map[string]string, next func(any) error) HandleFunc {
		var id string
		if len(ir.Body) > 0 && ir.Body["id"] != "" {
			id = cast.ToString(ir.Body["id"])
		}
		if id != "" {
			_, err := app.FindRecordById(params["collection"], id)
			if err == nil {

				params["id"] = id
				ir.Method = "PATCH"
				ir.URL = "/api/collections/" + params["collection"] + "/records/" + id + params["query"]
				return recordUpdate(next)
			}
		}

		ir.Method = "POST"
		ir.URL = "/api/collections/" + params["collection"] + "/records" + params["query"]
		return recordCreate(next)
	},
	regexp.MustCompile(`^POST /api/collections/(?P<collection>[^\/\?]+)/records(\?.*)?$`): func(app core.App, ir *core.InternalRequest, params map[string]string, next func(any) error) HandleFunc {
		return recordCreate(next)
	},
	regexp.MustCompile(`^PATCH /api/collections/(?P<collection>[^\/\?]+)/records/(?P<id>[^\/\?]+)(\?.*)?$`): func(app core.App, ir *core.InternalRequest, params map[string]string, next func(any) error) HandleFunc {
		return recordUpdate(next)
	},
	regexp.MustCompile(`^DELETE /api/collections/(?P<collection>[^\/\?]+)/records/(?P<id>[^\/\?]+)(\?.*)?$`): func(app core.App, ir *core.InternalRequest, params map[string]string, next func(any) error) HandleFunc {
		return recordDelete(next)
	},
}

ValidBatchActions defines a map with the supported batch InternalRequest actions.

Note: when adding new routes make sure that their middlewares are inlined!

Functions

func BodyLimit added in v0.23.0

func BodyLimit(limitBytes int64) *hook.Handler[*core.RequestEvent]

BodyLimit returns a middleware handler that changes the default request body size limit.

If limitBytes <= 0, no limit is applied.

Otherwise, if the request body size exceeds the configured limitBytes, it sends 413 error response.

func CORS added in v0.23.0

func CORS(config CORSConfig) *hook.Handler[*core.RequestEvent]

CORS returns a CORS middleware.

func EnrichRecord added in v0.8.0

func EnrichRecord(e *core.RequestEvent, record *core.Record, defaultExpands ...string) error

EnrichRecord parses the request context and enrich the provided record:

  • expands relations (if defaultExpands and/or ?expand query param is set)
  • ensures that the emails of the auth record and its expanded auth relations are visible only for the current logged superuser, record owner or record with manage access

func EnrichRecords added in v0.8.0

func EnrichRecords(e *core.RequestEvent, records []*core.Record, defaultExpands ...string) error

EnrichRecords parses the request context and enriches the provided records:

  • expands relations (if defaultExpands and/or ?expand query param is set)
  • ensures that the emails of the auth records and their expanded auth relations are visible only for the current logged superuser, record owner or record with manage access

Note: Expects all records to be from the same collection!

func Gzip added in v0.23.0

func Gzip() *hook.Handler[*core.RequestEvent]

Gzip returns a middleware which compresses HTTP response using Gzip compression scheme.

func GzipWithConfig added in v0.23.0

func GzipWithConfig(config GzipConfig) *hook.Handler[*core.RequestEvent]

GzipWithConfig returns a middleware which compresses HTTP response using gzip compression scheme.

func MustSubFS added in v0.23.0

func MustSubFS(fsys fs.FS, dir string) fs.FS

MustSubFS returns an fs.FS corresponding to the subtree rooted at fsys's dir.

This is similar to fs.Sub but panics on failure.

func NewApiError added in v0.8.0

func NewApiError(status int, message string, errData any) *router.ApiError

NewApiError is an alias for router.NewApiError.

func NewBadRequestError added in v0.8.0

func NewBadRequestError(message string, errData any) *router.ApiError

NewBadRequestError is an alias for router.NewBadRequestError.

func NewForbiddenError added in v0.8.0

func NewForbiddenError(message string, errData any) *router.ApiError

NewForbiddenError is an alias for router.NewForbiddenError.

func NewInternalServerError added in v0.23.0

func NewInternalServerError(message string, errData any) *router.ApiError

NewInternalServerError is an alias for router.NewInternalServerError.

func NewNotFoundError added in v0.8.0

func NewNotFoundError(message string, errData any) *router.ApiError

NewNotFoundError is an alias for router.NewNotFoundError.

func NewRouter added in v0.23.0

func NewRouter(app core.App) (*router.Router[*core.RequestEvent], error)

NewRouter returns a new router instance loaded with the default app middlewares and api routes.

func NewTooManyRequestsError added in v0.23.0

func NewTooManyRequestsError(message string, errData any) *router.ApiError

NewTooManyRequestsError is an alias for router.NewTooManyRequestsError.

func NewUnauthorizedError added in v0.8.0

func NewUnauthorizedError(message string, errData any) *router.ApiError

NewUnauthorizedError is an alias for router.NewUnauthorizedError.

func RecordAuthResponse added in v0.12.0

func RecordAuthResponse(e *core.RequestEvent, authRecord *core.Record, authMethod string, meta any) error

RecordAuthResponse writes standardized json record auth response into the specified request context.

The authMethod argument specify the name of the current authentication method (eg. password, oauth2, etc.) that it is used primarily as an auth identifier during MFA and for login alerts.

Set authMethod to empty string if you want to ignore the MFA checks and the login alerts (can be also adjusted additionally via the OnRecordAuthRequest hook).

func RequireAuth added in v0.23.0

func RequireAuth(optCollectionNames ...string) *hook.Handler[*core.RequestEvent]

RequireAuth middleware requires a request to have a valid record Authorization header.

The auth record could be from any collection. You can further filter the allowed record auth collections by specifying their names.

Example:

apis.RequireAuth()                      // any auth collection
apis.RequireAuth("_superusers", "users") // only the listed auth collections

func RequireGuestOnly

func RequireGuestOnly() *hook.Handler[*core.RequestEvent]

RequireGuestOnly middleware requires a request to NOT have a valid Authorization header.

This middleware is the opposite of [apis.RequireAuth()].

func RequireSameCollectionContextAuth added in v0.23.0

func RequireSameCollectionContextAuth(collectionPathParam string) *hook.Handler[*core.RequestEvent]

RequireSameCollectionContextAuth middleware requires a request to have a valid record Authorization header and the auth record's collection to match the one from the route path parameter (default to "collection" if collectionParam is empty).

func RequireSuperuserAuth added in v0.23.0

func RequireSuperuserAuth() *hook.Handler[*core.RequestEvent]

RequireSuperuserAuth middleware requires a request to have a valid superuser Authorization header.

func RequireSuperuserOrOwnerAuth added in v0.23.0

func RequireSuperuserOrOwnerAuth(ownerIdPathParam string) *hook.Handler[*core.RequestEvent]

RequireSuperuserOrOwnerAuth middleware requires a request to have a valid superuser or regular record owner Authorization header set.

This middleware is similar to [apis.RequireAuth()] but for the auth record token expects to have the same id as the path parameter ownerIdPathParam (default to "id" if empty).

func Serve added in v0.16.0

func Serve(app core.App, config ServeConfig) error

Serve starts a new app web server.

NB! The app should be bootstrapped before starting the web server.

Example:

app.Bootstrap()
apis.Serve(app, apis.ServeConfig{
	HttpAddr:        "127.0.0.1:8080",
	ShowStartBanner: false,
})

func SkipSuccessActivityLog added in v0.23.0

func SkipSuccessActivityLog() *hook.Handler[*core.RequestEvent]

SkipSuccessActivityLog is a helper middleware that instructs the global activity logger to log only requests that have failed/returned an error.

func Static added in v0.23.0

func Static(fsys fs.FS, indexFallback bool) func(*core.RequestEvent) error

Static is a handler function to serve static directory content from fsys.

If a file resource is missing and indexFallback is set, the request will be forwarded to the base index.html (useful for SPA with pretty urls).

NB! Expects the route to have a "{path...}" wildcard parameter.

Special redirects:

  • if "path" is a file that ends in index.html, it is redirected to its non-index.html version (eg. /test/index.html -> /test/)
  • if "path" is a directory that has index.html, the index.html file is rendered, otherwise if missing - returns 404 or fallback to the root index.html if indexFallback is set

Example:

fsys := os.DirFS("./pb_public")
router.GET("/files/{path...}", apis.Static(fsys, false))

func ToApiError added in v0.23.0

func ToApiError(err error) *router.ApiError

ToApiError wraps err into ApiError instance (if not already).

func WrapStdHandler added in v0.23.0

func WrapStdHandler(h http.Handler) func(*core.RequestEvent) error

WrapStdHandler wraps Go http.Handler into a PocketBase handler func.

func WrapStdMiddleware added in v0.23.0

func WrapStdMiddleware(m func(http.Handler) http.Handler) func(*core.RequestEvent) error

WrapStdMiddleware wraps Go [func(http.Handler) http.Handle] into a PocketBase middleware func.

Types

type BatchActionHandlerFunc added in v0.23.0

type BatchActionHandlerFunc func(app core.App, ir *core.InternalRequest, params map[string]string, next func(data any) error) HandleFunc

type BatchRequestResult added in v0.23.0

type BatchRequestResult struct {
	Body   any `json:"body"`
	Status int `json:"status"`
}

type BatchResponseError added in v0.23.0

type BatchResponseError struct {
	// contains filtered or unexported fields
}

func (*BatchResponseError) Code added in v0.23.0

func (e *BatchResponseError) Code() string

func (*BatchResponseError) Error added in v0.23.0

func (e *BatchResponseError) Error() string

func (BatchResponseError) MarshalJSON added in v0.23.0

func (e BatchResponseError) MarshalJSON() ([]byte, error)

func (*BatchResponseError) Resolve added in v0.23.0

func (e *BatchResponseError) Resolve(errData map[string]any) any

type CORSConfig added in v0.23.0

type CORSConfig struct {
	// AllowOrigins determines the value of the Access-Control-Allow-Origin
	// response header.  This header defines a list of origins that may access the
	// resource.  The wildcard characters '*' and '?' are supported and are
	// converted to regex fragments '.*' and '.' accordingly.
	//
	// Security: use extreme caution when handling the origin, and carefully
	// validate any logic. Remember that attackers may register hostile domain names.
	// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
	//
	// Optional. Default value []string{"*"}.
	//
	// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
	AllowOrigins []string

	// AllowOriginFunc is a custom function to validate the origin. It takes the
	// origin as an argument and returns true if allowed or false otherwise. If
	// an error is returned, it is returned by the handler. If this option is
	// set, AllowOrigins is ignored.
	//
	// Security: use extreme caution when handling the origin, and carefully
	// validate any logic. Remember that attackers may register hostile domain names.
	// See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
	//
	// Optional.
	AllowOriginFunc func(origin string) (bool, error)

	// AllowMethods determines the value of the Access-Control-Allow-Methods
	// response header.  This header specified the list of methods allowed when
	// accessing the resource.  This is used in response to a preflight request.
	//
	// Optional. Default value DefaultCORSConfig.AllowMethods.
	//
	// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
	AllowMethods []string

	// AllowHeaders determines the value of the Access-Control-Allow-Headers
	// response header.  This header is used in response to a preflight request to
	// indicate which HTTP headers can be used when making the actual request.
	//
	// Optional. Default value []string{}.
	//
	// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
	AllowHeaders []string

	// AllowCredentials determines the value of the
	// Access-Control-Allow-Credentials response header.  This header indicates
	// whether or not the response to the request can be exposed when the
	// credentials mode (Request.credentials) is true. When used as part of a
	// response to a preflight request, this indicates whether or not the actual
	// request can be made using credentials.  See also
	// [MDN: Access-Control-Allow-Credentials].
	//
	// Optional. Default value false, in which case the header is not set.
	//
	// Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`.
	// See "Exploiting CORS misconfigurations for Bitcoins and bounties",
	// https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
	//
	// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
	AllowCredentials bool

	// UnsafeWildcardOriginWithAllowCredentials UNSAFE/INSECURE: allows wildcard '*' origin to be used with AllowCredentials
	// flag. In that case we consider any origin allowed and send it back to the client with `Access-Control-Allow-Origin` header.
	//
	// This is INSECURE and potentially leads to [cross-origin](https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bounties)
	// attacks. See: https://github.com/labstack/echo/issues/2400 for discussion on the subject.
	//
	// Optional. Default value is false.
	UnsafeWildcardOriginWithAllowCredentials bool

	// ExposeHeaders determines the value of Access-Control-Expose-Headers, which
	// defines a list of headers that clients are allowed to access.
	//
	// Optional. Default value []string{}, in which case the header is not set.
	//
	// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Header
	ExposeHeaders []string

	// MaxAge determines the value of the Access-Control-Max-Age response header.
	// This header indicates how long (in seconds) the results of a preflight
	// request can be cached.
	// The header is set only if MaxAge != 0, negative value sends "0" which instructs browsers not to cache that response.
	//
	// Optional. Default value 0 - meaning header is not sent.
	//
	// See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
	MaxAge int
}

CORSConfig defines the config for CORS middleware.

type EmailChangeConfirmForm added in v0.23.0

type EmailChangeConfirmForm struct {
	Token    string `form:"token" json:"token"`
	Password string `form:"password" json:"password"`
	// contains filtered or unexported fields
}

type GzipConfig added in v0.23.0

type GzipConfig struct {
	// Gzip compression level.
	// Optional. Default value -1.
	Level int

	// Length threshold before gzip compression is applied.
	// Optional. Default value 0.
	//
	// Most of the time you will not need to change the default. Compressing
	// a short response might increase the transmitted data because of the
	// gzip format overhead. Compressing the response will also consume CPU
	// and time on the server and the client (for decompressing). Depending on
	// your use case such a threshold might be useful.
	//
	// See also:
	// https://webmasters.stackexchange.com/questions/31750/what-is-recommended-minimum-object-size-for-gzip-performance-benefits
	MinLength int
}

GzipConfig defines the config for Gzip middleware.

type HandleFunc added in v0.23.0

type HandleFunc func(e *core.RequestEvent) error

type ServeConfig added in v0.17.0

type ServeConfig struct {
	// ShowStartBanner indicates whether to show or hide the server start console message.
	ShowStartBanner bool

	// HttpAddr is the TCP address to listen for the HTTP server (eg. "127.0.0.1:80").
	HttpAddr string

	// HttpsAddr is the TCP address to listen for the HTTPS server (eg. "127.0.0.1:443").
	HttpsAddr string

	// Optional domains list to use when issuing the TLS certificate.
	//
	// If not set, the host from the bound server address will be used.
	//
	// For convenience, for each "non-www" domain a "www" entry and
	// redirect will be automatically added.
	CertificateDomains []string

	// AllowedOrigins is an optional list of CORS origins (default to "*").
	AllowedOrigins []string
}

ServeConfig defines a configuration struct for apis.Serve().

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL