@lowdefy/docs-content 0.0.0-experimental-20260909201552 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/content/actions/login.md +5 -23
- package/content/actions/logout.md +5 -5
- package/content/agents/agentchat.md +1 -13
- package/content/concepts/ai-agent-docs.md +4 -90
- package/content/concepts/custom-styling.md +5 -50
- package/content/concepts/events-and-actions.md +2 -64
- package/content/concepts/i18n.md +1 -1
- package/content/connections/mongodb.md +3 -109
- package/content/container-blocks/modal.md +1 -1
- package/content/container-blocks/pagesidebarlayout.md +0 -1
- package/content/controls/reject.md +1 -3
- package/content/controls/throw.md +0 -1
- package/content/controls/try.md +2 -3
- package/content/display-blocks/difflist.md +1 -1
- package/content/display-blocks/difftimeline.md +1 -1
- package/content/display-blocks/s3download.md +1 -1
- package/content/display-blocks/search.md +0 -1
- package/content/input-blocks/checkboxselector.md +4 -80
- package/content/input-blocks/radioselector.md +3 -65
- package/content/input-blocks/s3uploadbutton.md +1 -1
- package/content/input-blocks/s3uploaddragger.md +1 -1
- package/content/input-blocks/s3uploadphoto.md +1 -1
- package/content/input-blocks/tiptapmentioninput.md +1 -1
- package/content/list-blocks/masonrylist.md +1 -1
- package/content/operators/_type.md +3 -14
- package/content/operators/_user.md +3 -3
- package/content/user-authentication/login-and-logout.md +8 -158
- package/content/user-authentication/users-introduction.md +0 -8
- package/index.json +1 -99
- package/package.json +1 -3
- package/content/actions/emailotpsend.md +0 -58
- package/content/actions/emailotpverify.md +0 -77
- package/content/actions/magiclinkverify.md +0 -113
- package/content/controls/while.md +0 -46
- package/content/input-blocks/captcha.md +0 -40
- package/content/input-blocks/tagmultipleselector.md +0 -101
- package/content/input-blocks/tagselector.md +0 -101
- package/content/migration/auth-upgrade.md +0 -315
- package/content/other/mongodbadapter.md +0 -3
- package/content/user-authentication/auth-steps.md +0 -111
- package/content/user-authentication/mcp-oauth.md +0 -289
- package/content/user-authentication/organizations.md +0 -134
- package/content/user-authentication/two-factor.md +0 -225
- package/content/user-authentication/user-object.md +0 -58
- package/hazards.json +0 -44
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# User Object
|
|
2
|
-
|
|
3
|
-
The `user` object holds data about the currently signed-in **caller**, read with the [`_user`](/_user) operator on both the server and the client. It is not the provider's profile — it is a caller Lowdefy resolves from the user's row *and their membership in the active organization*, so the same person carries a different `_user` in two organizations they belong to.
|
|
4
|
-
|
|
5
|
-
Its shape is **fixed**. Unlike the old provider-claim mapping, there is no `userFields` config and no set of OpenID Connect claims copied onto the session — the provider subject and extra claims are not on the user object at all. If you need a provider claim at signup, persist it with an [auth hook](/auth-upgrade#7-rewrite-callbacks-and-events-as-hooks) and read it from where you stored it.
|
|
6
|
-
|
|
7
|
-
## Fields
|
|
8
|
-
|
|
9
|
-
| Field | On which callers | Meaning |
|
|
10
|
-
| ----- | ---------------- | ------- |
|
|
11
|
-
| `id` | all | The internal user id. **This replaces the old `sub`** — it is a *different value* (the provider subject lives on the `user-accounts` collection as `accountId`). |
|
|
12
|
-
| `email` | all | The user's email. |
|
|
13
|
-
| `email_verified` | session | Whether the email is verified. |
|
|
14
|
-
| `name`, `image` | session | Display name and avatar — the **per-organization** copies from the active membership, falling back to the deployment-global user record. |
|
|
15
|
-
| `roles` | session, strategy | The app's own role strings, from the active membership's `appRoles`. **The only thing `auth.pages.roles` / `auth.api.roles` match.** |
|
|
16
|
-
| `org_roles` | session | The organization tier from `member.role`: `owner`, `admin` or `member`. An administrative fact — **no gate reads it**. |
|
|
17
|
-
| `attributes` | session | One merged bag: global `user.attributes` under the active `member.attributes`, per key, member wins. |
|
|
18
|
-
| `organization_id` | session, mcp | The organization the caller acts in — the value the [tenant wall](/organizations#the-tenant-wall) stamps and filters on. |
|
|
19
|
-
| `active_organization_id` | session | The active organization id (equal to `organization_id`). |
|
|
20
|
-
| `two_factor_enrolled` | session | Whether the caller holds a factor satisfying `auth.twoFactor.required`. |
|
|
21
|
-
| `auth_method` | strategy, mcp | How the caller authenticated — the strategy id, or `'mcp'` for an [assistant](/mcp-oauth). Absent on browser sessions. |
|
|
22
|
-
| `profile` | session | The user record's opaque display/app-data bag. Absent (never `{}`) when the user has written no profile. |
|
|
23
|
-
| `contact_id` | session | Link to the app's canonical record for this person, when one exists. |
|
|
24
|
-
|
|
25
|
-
> **`_user.role` (singular) carries nothing.** Lowdefy never writes it; it sits one character from `roles`, so gating on `_user.role` is gating on a constant. Read `roles`.
|
|
26
|
-
|
|
27
|
-
A caller resolved from an [API strategy](/auth-configuration) (`apiKey`, `jwt`) sits outside the membership boundary: it carries `id`, `roles`, `attributes` and `auth_method`, but no organization, `name`, `image`, `profile` or `two_factor_enrolled`. A signed-in user who holds only a pending invitation (before they accept, under `tenant`) is an *awaiting-organization* caller — known to the always-public accept page, refused everywhere else.
|
|
28
|
-
|
|
29
|
-
## Examples
|
|
30
|
-
|
|
31
|
-
###### Use the user's avatar in an Avatar block:
|
|
32
|
-
```yaml
|
|
33
|
-
id: avatar
|
|
34
|
-
type: Avatar
|
|
35
|
-
properties:
|
|
36
|
-
src:
|
|
37
|
-
_user: image
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
###### Stamp the creator when inserting a document:
|
|
41
|
-
```yaml
|
|
42
|
-
id: insert_data
|
|
43
|
-
type: MongoDBInsertOne
|
|
44
|
-
properties:
|
|
45
|
-
doc:
|
|
46
|
-
field:
|
|
47
|
-
_state: field
|
|
48
|
-
created_by:
|
|
49
|
-
name:
|
|
50
|
-
_user: name
|
|
51
|
-
id:
|
|
52
|
-
_user: id
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
###### Read a value out of the merged attributes bag:
|
|
56
|
-
```yaml
|
|
57
|
-
_user: attributes.plan
|
|
58
|
-
```
|
package/hazards.json
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "state-in-request-properties",
|
|
4
|
-
"appliesTo": { "kinds": ["requests"] },
|
|
5
|
-
"message": "_state in request properties is always undefined — a request is evaluated on the server with an empty state. Pass the value in the payload and read it with _payload.",
|
|
6
|
-
"see": "concepts/connections-and-requests"
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
"id": "visible-false-prunes-state",
|
|
10
|
-
"appliesTo": { "kinds": ["blocks"] },
|
|
11
|
-
"message": "visible: false removes the block and its state. Style it hidden (for example style: { display: none }) to keep the value.",
|
|
12
|
-
"see": "concepts/lowdefy-schema"
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"id": "link-same-page-no-onmount",
|
|
16
|
-
"appliesTo": { "types": ["Link"] },
|
|
17
|
-
"message": "A Link to the page already open does not remount it, so onMount does not fire again. Trigger the reload chain from the same action list.",
|
|
18
|
-
"see": "actions/link"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"id": "ref-njk-renders-at-build",
|
|
22
|
-
"appliesTo": { "types": ["_ref"] },
|
|
23
|
-
"message": "A _ref to a .njk file renders at build, so _state, _request and _user are undefined inside it. Use _nunjucks over a .txt file for a template that needs runtime values.",
|
|
24
|
-
"see": "operators/_ref"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"id": "ref-js-imported-as-module",
|
|
28
|
-
"appliesTo": { "types": ["_ref"] },
|
|
29
|
-
"message": "A _ref to a .js file imports it as a module rather than reading it as text. Name the file .js.txt to read its source.",
|
|
30
|
-
"see": "operators/_ref"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"id": "tenant-wall-lookup",
|
|
34
|
-
"appliesTo": { "kinds": ["requests"], "when": "connectionTenantNotNone" },
|
|
35
|
-
"message": "This request runs over a tenant-walled connection. The wall injects { $match: { <tenant field> } } into the top-level pipeline and into every $lookup / $unionWith sub-pipeline, so a lookup into a collection with no tenant field returns [] with no error. Run the request over the shared connection and pass tenant facts in the payload instead.",
|
|
36
|
-
"see": "concepts/connections-and-requests"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"id": "reject-not-caught",
|
|
40
|
-
"appliesTo": { "types": [":reject"] },
|
|
41
|
-
"message": ":reject is the routine's reply, not an exception. A :catch never runs for it, :finally does, and :throw is the caught path.",
|
|
42
|
-
"see": "controls/reject"
|
|
43
|
-
}
|
|
44
|
-
]
|