Files
zeekay 23cf129160 Field types for people and money, and the caller's org authority in rules
Seven field types a CRM record needs, each one JSON column whose parts a
filter, a sort or an aggregate reaches by name: currency (amountMicros,
currencyCode), emails, phones, links, address, fullName and actor, plus
rating. Empty is NULL. Emails, phones and links normalize what is typed and
can keep their primary part unique. An actor is stamped by the server from
the writer the save's context states; nothing a request sends sets it.

Every field carries a label, description, icon and position, a select's
values carry a label, colour and position, and a base collection carries a
label, plural, icon, description and an opt-in history flag.

Editor HTML is sanitized before it is written.

A rule reads the caller's authority in the org it acts in:
@request.auth.admin and @request.auth.role, off the token. An IAM-mirrored
auth record is never saved, so its fields are now read off the record
rather than joined against a row that is not there, which also makes
@request.auth.org_id match for the first time. A host that opens one Base
per org names it, and a token acting in another org is refused there.
2026-10-18 20:41:15 -07:00

37 lines
1.2 KiB
Go

package apis
import (
"context"
"github.com/hanzoai/base/core"
"github.com/hanzoai/base/tools/types"
)
// WithRequestActor is the request's context with the writer stated, for the
// records the request saves: an actor field stamps it and a collection's
// history records it (see [core.WithActor]).
func WithRequestActor(e *core.RequestEvent) context.Context {
return core.WithActor(e.Request.Context(), RequestActor(e))
}
// RequestActor answers who a request writes as: the person it authenticated as,
// an org's own key, or — with no credential — an anonymous caller of a public
// route.
func RequestActor(e *core.RequestEvent) types.Actor {
if e.Auth != nil {
name := e.Auth.GetString("name")
if name == "" {
name = e.Auth.GetString(core.FieldNameEmail)
}
return types.Actor{Source: core.ActorManual, Id: e.Auth.Id, Name: name}
}
// An IAM key mints no auth record, so its door names the subject instead.
if sub, _ := e.Get(RequestEventKeySub).(string); sub != "" {
name, _ := e.Get(RequestEventKeyName).(string)
return types.Actor{Source: core.ActorAPI, Id: sub, Name: name}
}
return types.Actor{Source: core.ActorAPI, Name: "Anonymous"}
}