mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-03-21 06:36:27 +02:00
added support for @request.headers.*
This commit is contained in:
parent
19faa0d8e7
commit
a67c14c368
@ -30,9 +30,18 @@ func RequestData(c echo.Context) *models.RequestData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result := &models.RequestData{
|
result := &models.RequestData{
|
||||||
Method: c.Request().Method,
|
Method: c.Request().Method,
|
||||||
Query: map[string]any{},
|
Query: map[string]any{},
|
||||||
Data: map[string]any{},
|
Data: map[string]any{},
|
||||||
|
Headers: map[string]string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract the first value of all headers and normalizes the keys
|
||||||
|
// ("X-Token" is converted to "x_token")
|
||||||
|
for k, v := range c.Request().Header {
|
||||||
|
if len(v) > 0 {
|
||||||
|
result.Headers[strings.ToLower(strings.ReplaceAll(k, "-", "_"))] = v[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result.AuthRecord, _ = c.Get(ContextAuthRecordKey).(*models.Record)
|
result.AuthRecord, _ = c.Get(ContextAuthRecordKey).(*models.Record)
|
||||||
|
@ -17,6 +17,7 @@ func TestRequestData(t *testing.T) {
|
|||||||
e := echo.New()
|
e := echo.New()
|
||||||
req := httptest.NewRequest(http.MethodPost, "/?test=123", strings.NewReader(`{"test":456}`))
|
req := httptest.NewRequest(http.MethodPost, "/?test=123", strings.NewReader(`{"test":456}`))
|
||||||
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
||||||
|
req.Header.Set("X-Token-Test", "123")
|
||||||
rec := httptest.NewRecorder()
|
rec := httptest.NewRecorder()
|
||||||
c := e.NewContext(req, rec)
|
c := e.NewContext(req, rec)
|
||||||
|
|
||||||
@ -38,6 +39,12 @@ func TestRequestData(t *testing.T) {
|
|||||||
t.Fatalf("Expected Method %v, got %v", http.MethodPost, result.Method)
|
t.Fatalf("Expected Method %v, got %v", http.MethodPost, result.Method)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawHeaders, _ := json.Marshal(result.Headers)
|
||||||
|
expectedHeaders := `{"content_type":"application/json","x_token_test":"123"}`
|
||||||
|
if v := string(rawHeaders); v != expectedHeaders {
|
||||||
|
t.Fatalf("Expected Query %v, got %v", expectedHeaders, v)
|
||||||
|
}
|
||||||
|
|
||||||
rawQuery, _ := json.Marshal(result.Query)
|
rawQuery, _ := json.Marshal(result.Query)
|
||||||
expectedQuery := `{"test":"123"}`
|
expectedQuery := `{"test":"123"}`
|
||||||
if v := string(rawQuery); v != expectedQuery {
|
if v := string(rawQuery); v != expectedQuery {
|
||||||
|
@ -9,11 +9,12 @@ import (
|
|||||||
// RequestData defines a HTTP request data struct, usually used
|
// RequestData defines a HTTP request data struct, usually used
|
||||||
// as part of the `@request.*` filter resolver.
|
// as part of the `@request.*` filter resolver.
|
||||||
type RequestData struct {
|
type RequestData struct {
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Query map[string]any `json:"query"`
|
Query map[string]any `json:"query"`
|
||||||
Data map[string]any `json:"data"`
|
Data map[string]any `json:"data"`
|
||||||
AuthRecord *Record `json:"authRecord"`
|
Headers map[string]string `json:"headers"`
|
||||||
Admin *Admin `json:"admin"`
|
AuthRecord *Record `json:"authRecord"`
|
||||||
|
Admin *Admin `json:"admin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasModifierDataKeys loosely checks if the current struct has any modifier Data keys.
|
// HasModifierDataKeys loosely checks if the current struct has any modifier Data keys.
|
||||||
|
@ -84,6 +84,7 @@ func NewRecordFieldResolver(
|
|||||||
`^\@request\.auth\.[\w\.\:]*\w+$`,
|
`^\@request\.auth\.[\w\.\:]*\w+$`,
|
||||||
`^\@request\.data\.[\w\.\:]*\w+$`,
|
`^\@request\.data\.[\w\.\:]*\w+$`,
|
||||||
`^\@request\.query\.[\w\.\:]*\w+$`,
|
`^\@request\.query\.[\w\.\:]*\w+$`,
|
||||||
|
`^\@request\.headers\.\w+$`,
|
||||||
`^\@collection\.\w+\.[\w\.\:]*\w+$`,
|
`^\@collection\.\w+\.[\w\.\:]*\w+$`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -92,6 +93,7 @@ func NewRecordFieldResolver(
|
|||||||
if r.requestData != nil {
|
if r.requestData != nil {
|
||||||
r.staticRequestData["method"] = r.requestData.Method
|
r.staticRequestData["method"] = r.requestData.Method
|
||||||
r.staticRequestData["query"] = r.requestData.Query
|
r.staticRequestData["query"] = r.requestData.Query
|
||||||
|
r.staticRequestData["headers"] = r.requestData.Headers
|
||||||
r.staticRequestData["data"] = r.requestData.Data
|
r.staticRequestData["data"] = r.requestData.Data
|
||||||
r.staticRequestData["auth"] = nil
|
r.staticRequestData["auth"] = nil
|
||||||
if r.requestData.AuthRecord != nil {
|
if r.requestData.AuthRecord != nil {
|
||||||
@ -132,6 +134,7 @@ func (r *RecordFieldResolver) UpdateQuery(query *dbx.SelectQuery) error {
|
|||||||
// project.screen.status
|
// project.screen.status
|
||||||
// @request.status
|
// @request.status
|
||||||
// @request.query.filter
|
// @request.query.filter
|
||||||
|
// @request.headers.x_token
|
||||||
// @request.auth.someRelation.name
|
// @request.auth.someRelation.name
|
||||||
// @request.data.someRelation.name
|
// @request.data.someRelation.name
|
||||||
// @request.data.someField
|
// @request.data.someField
|
||||||
|
@ -23,6 +23,10 @@ func TestRecordFieldResolverUpdateQuery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requestData := &models.RequestData{
|
requestData := &models.RequestData{
|
||||||
|
Headers: map[string]string{
|
||||||
|
"a": "123",
|
||||||
|
"b": "456",
|
||||||
|
},
|
||||||
Query: map[string]any{
|
Query: map[string]any{
|
||||||
"a": nil,
|
"a": nil,
|
||||||
"b": 123,
|
"b": 123,
|
||||||
@ -438,6 +442,9 @@ func TestRecordFieldResolverResolveStaticRequestDataFields(t *testing.T) {
|
|||||||
"b": 456,
|
"b": 456,
|
||||||
"c": map[string]int{"sub": 1},
|
"c": map[string]int{"sub": 1},
|
||||||
},
|
},
|
||||||
|
Headers: map[string]string{
|
||||||
|
"d": "789",
|
||||||
|
},
|
||||||
AuthRecord: authRecord,
|
AuthRecord: authRecord,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,6 +463,10 @@ func TestRecordFieldResolverResolveStaticRequestDataFields(t *testing.T) {
|
|||||||
{"@request.query", true, ``},
|
{"@request.query", true, ``},
|
||||||
{"@request.query.a", false, `123`},
|
{"@request.query.a", false, `123`},
|
||||||
{"@request.query.a.missing", false, ``},
|
{"@request.query.a.missing", false, ``},
|
||||||
|
{"@request.headers", true, ``},
|
||||||
|
{"@request.headers.missing", false, ``},
|
||||||
|
{"@request.headers.d", false, `456`},
|
||||||
|
{"@request.headers.d.sub", true, ``},
|
||||||
{"@request.data", true, ``},
|
{"@request.data", true, ``},
|
||||||
{"@request.data.b", false, `456`},
|
{"@request.data.b", false, `456`},
|
||||||
{"@request.data.number", false, `10`}, // number field normalization
|
{"@request.data.number", false, `10`}, // number field normalization
|
||||||
|
@ -256,6 +256,7 @@
|
|||||||
result.push("@request.method");
|
result.push("@request.method");
|
||||||
result.push("@request.query.");
|
result.push("@request.query.");
|
||||||
result.push("@request.data.");
|
result.push("@request.data.");
|
||||||
|
result.push("@request.headers.");
|
||||||
result.push("@request.auth.id");
|
result.push("@request.auth.id");
|
||||||
result.push("@request.auth.collectionId");
|
result.push("@request.auth.collectionId");
|
||||||
result.push("@request.auth.collectionName");
|
result.push("@request.auth.collectionName");
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
The request fields could be accessed with the special <em>@request</em> filter:
|
The request fields could be accessed with the special <em>@request</em> filter:
|
||||||
</p>
|
</p>
|
||||||
<div class="inline-flex flex-gap-5">
|
<div class="inline-flex flex-gap-5">
|
||||||
<code>@request.method</code>
|
<code>@request.headers.*</code>
|
||||||
<code>@request.query.*</code>
|
<code>@request.query.*</code>
|
||||||
<code>@request.data.*</code>
|
<code>@request.data.*</code>
|
||||||
<code>@request.auth.*</code>
|
<code>@request.auth.*</code>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user