@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,6 +1,6 @@
|
|
|
1
1
|
# Modal
|
|
2
2
|
|
|
3
|
-
Modal dialog overlay for focused content. Add `shortcut: Escape` to the `onClose` event to run custom actions when Escape is pressed. Ant Design
|
|
3
|
+
Modal dialog overlay for focused content. Add `shortcut: Escape` to the `onClose` event to run custom actions when Escape is pressed. Ant Design's Modal already closes on Escape by default — the shortcut triggers your custom actions in addition to the built-in close.
|
|
4
4
|
|
|
5
5
|
This is a basic modal dialog with a title, content area, and default Ok/Cancel buttons.
|
|
6
6
|
|
|
@@ -411,7 +411,6 @@ Dashboard Overview
|
|
|
411
411
|
| `/mobileMenu` | The PageSidebarLayout mobile menu. |
|
|
412
412
|
| `/header` | The PageSidebarLayout header. |
|
|
413
413
|
| `/headerActions` | The header actions container (notifications, profile, dark mode toggle). |
|
|
414
|
-
| `/headerContent` | The PageSidebarLayout header content area (the header slot row). |
|
|
415
414
|
| `/logo` | The PageSidebarLayout logo. |
|
|
416
415
|
| `/notifications` | The notification bell button. |
|
|
417
416
|
| `/notificationsBadge` | The notification badge wrapper. |
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
The `:reject` control is used to return a user-friendly error to the client when validation fails or business rules are violated.
|
|
8
8
|
Unlike [`:throw`](/:throw), which indicates a system error, `:reject` represents an expected failure condition that should be communicated to the user.
|
|
9
9
|
The control immediately stops routine execution and returns with a `"reject"` status.
|
|
10
|
-
Importantly, `:reject` does not trigger `:catch` blocks in [`:try`](/:try) statements
|
|
11
|
-
This makes `:reject` ideal for handling validation and business logic errors separately from system errors.
|
|
12
|
-
Choose [`:throw`](/:throw) when a step failed and the routine may recover; choose `:reject` when the routine decided the request cannot be fulfilled.
|
|
10
|
+
Importantly, `:reject` does not trigger `:catch` blocks in [`:try`](/:try) statements, making it ideal for handling validation and business logic errors separately from system errors.
|
|
13
11
|
|
|
14
12
|
#### Keys
|
|
15
13
|
|
|
@@ -8,7 +8,6 @@ The `:throw` control creates a system error that immediately stops routine execu
|
|
|
8
8
|
Unlike [`:reject`](/:reject), which handles expected user errors, `:throw` is designed for unexpected system failures, programming errors, or critical issues that require attention.
|
|
9
9
|
The key difference is that `:throw` can be caught and handled by [`:try`](/:try)/`:catch` blocks, while [`:reject`](/:reject) cannot.
|
|
10
10
|
This makes `:throw` ideal for recoverable system errors where you might want to implement fallback logic.
|
|
11
|
-
Choose `:throw` when a step failed and the routine may recover; choose [`:reject`](/:reject) when the routine decided the request cannot be fulfilled.
|
|
12
11
|
|
|
13
12
|
#### Keys
|
|
14
13
|
|
package/content/controls/try.md
CHANGED
|
@@ -7,13 +7,12 @@
|
|
|
7
7
|
If one control in the routine chain defined in the `:try` key fails by throwing an error, the steps in the list following the failed control will not be executed.
|
|
8
8
|
To handle any errors thrown by a routine element, a routine can be provided using `catch` key.
|
|
9
9
|
The routine defined using the `:finally` key will be run regardless of whether or not the routine throws an error.
|
|
10
|
-
A [`:reject`](/:reject) inside the `:try` routine is __not__ caught. `:reject` is the routine's own reply — it stops the routine, returns a `"reject"` status to the caller, and flows past every enclosing `:catch`. `:finally` still runs. Use [`:throw`](/:throw) for failures a `:catch` should handle.
|
|
11
10
|
|
|
12
11
|
#### Keys
|
|
13
12
|
|
|
14
13
|
- `:try: routine`: __Required__ - The routine to be run.
|
|
15
|
-
- `:catch: routine`: The routine to execute if any step in the routine defined errors.
|
|
16
|
-
- `:finally: routine`: The routine to be run regardless of the out come of the initial routine.
|
|
14
|
+
- `:catch: routine`: The routine to execute if any step in the routine defined errors.
|
|
15
|
+
- `:finally: routine`: The routine to be run regardless of the out come of the initial routine.
|
|
17
16
|
|
|
18
17
|
#### Examples
|
|
19
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DiffList
|
|
2
2
|
|
|
3
|
-
`DiffList` renders a polished, user-friendly diff between a `before` and an `after` object as a grouped table of changes. Built on `microdiff` for the diff engine and antd primitives for rendering, it groups changes by top-level key, tags each row as Added / Removed / Changed, and supports per-path value formatters (`date`, `datetime`, `boolean`, `currency`, `enum`, `json`, `code`), humanised `labels`, and `hide` / `show` glob filtering. All colours come from antd
|
|
3
|
+
`DiffList` renders a polished, user-friendly diff between a `before` and an `after` object as a grouped table of changes. Built on `microdiff` for the diff engine and antd primitives for rendering, it groups changes by top-level key, tags each row as Added / Removed / Changed, and supports per-path value formatters (`date`, `datetime`, `boolean`, `currency`, `enum`, `json`, `code`), humanised `labels`, and `hide` / `show` glob filtering. All colours come from antd's semantic tokens so dark mode and `theme` overrides work automatically.
|
|
4
4
|
|
|
5
5
|
```yaml
|
|
6
6
|
- id: diff_list_profile
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DiffTimeline
|
|
2
2
|
|
|
3
|
-
`DiffTimeline` renders a diff as a vertical audit trail using Ant Design
|
|
3
|
+
`DiffTimeline` renders a diff as a vertical audit trail using Ant Design's `Timeline` component. Each change becomes a timeline entry with a colour-coded dot (green for added, red for removed, blue for changed) and a breadcrumb-style label that shows the full path to the changed field. Uses the same filtering, labelling, and per-path value formatters as `DiffList`.
|
|
4
4
|
|
|
5
5
|
```yaml
|
|
6
6
|
- id: diff_timeline_order
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# S3Download
|
|
2
2
|
|
|
3
|
-
__Deprecated__ — use the provider-neutral
|
|
3
|
+
__Deprecated__ — use the provider-neutral <a href="/Download">Download</a> block with `downloadPolicyRequestId` instead. S3Download remains as an alias so existing apps keep working. Download files from AWS S3. Requires an AwsS3Bucket connection and an AwsS3PresignedGetObject request. The s3GetPolicyRequestId property must reference the request id. If files were uploaded with S3Upload, its fileList value can be mapped directly to this block.
|
|
4
4
|
|
|
5
5
|
> The S3Download block requires an AwsS3Bucket connection and an AwsS3PresignedGetObject request. The examples below show configuration structure but will not download files without a configured connection.
|
|
6
6
|
|
|
@@ -356,6 +356,5 @@ See the [MiniSearch API docs](https://lucaong.github.io/minisearch/classes/MiniS
|
|
|
356
356
|
| `/itemDescription` | The description/snippet in a result item. |
|
|
357
357
|
| `/highlight` | Highlighted match text (<mark> elements). |
|
|
358
358
|
| `/empty` | The empty state message. |
|
|
359
|
-
| `/loading` | The loading spinner container. |
|
|
360
359
|
|
|
361
360
|
No slots defined.
|
|
@@ -703,89 +703,13 @@ Checkbox group for selecting multiple options.
|
|
|
703
703
|
valueKey: id
|
|
704
704
|
```
|
|
705
705
|
|
|
706
|
-
```yaml
|
|
707
|
-
- id: columns_two
|
|
708
|
-
type: CheckboxSelector
|
|
709
|
-
properties:
|
|
710
|
-
title: Two columns
|
|
711
|
-
columns: 2
|
|
712
|
-
options:
|
|
713
|
-
- Weekday mornings
|
|
714
|
-
- Weekday afternoons
|
|
715
|
-
- Weekday evenings
|
|
716
|
-
- Weekend mornings
|
|
717
|
-
- Weekend afternoons
|
|
718
|
-
- Weekend evenings
|
|
719
|
-
- id: columns_four
|
|
720
|
-
type: CheckboxSelector
|
|
721
|
-
properties:
|
|
722
|
-
title: Four columns
|
|
723
|
-
columns: 4
|
|
724
|
-
options:
|
|
725
|
-
- January
|
|
726
|
-
- February
|
|
727
|
-
- March
|
|
728
|
-
- April
|
|
729
|
-
- May
|
|
730
|
-
- June
|
|
731
|
-
- July
|
|
732
|
-
- August
|
|
733
|
-
- id: columns_responsive
|
|
734
|
-
type: CheckboxSelector
|
|
735
|
-
properties:
|
|
736
|
-
title: One column below md, three from md up
|
|
737
|
-
columns:
|
|
738
|
-
xs: 1
|
|
739
|
-
md: 3
|
|
740
|
-
options:
|
|
741
|
-
- Email
|
|
742
|
-
- SMS
|
|
743
|
-
- Push notification
|
|
744
|
-
- Webhook
|
|
745
|
-
- In-app message
|
|
746
|
-
- Weekly digest
|
|
747
|
-
- id: columns_gutter
|
|
748
|
-
type: CheckboxSelector
|
|
749
|
-
properties:
|
|
750
|
-
title: Wider gutter
|
|
751
|
-
columns: 2
|
|
752
|
-
gutter:
|
|
753
|
-
- 24
|
|
754
|
-
- 12
|
|
755
|
-
options:
|
|
756
|
-
- Read
|
|
757
|
-
- Write
|
|
758
|
-
- Delete
|
|
759
|
-
- Administer
|
|
760
|
-
- id: columns_per_option_color
|
|
761
|
-
type: CheckboxSelector
|
|
762
|
-
properties:
|
|
763
|
-
title: Coloured options in a grid
|
|
764
|
-
columns: 2
|
|
765
|
-
options:
|
|
766
|
-
- label: Low
|
|
767
|
-
value: low
|
|
768
|
-
color: "#16a34a"
|
|
769
|
-
- label: Medium
|
|
770
|
-
value: medium
|
|
771
|
-
color: "#d97706"
|
|
772
|
-
- label: High
|
|
773
|
-
value: high
|
|
774
|
-
color: "#dc2626"
|
|
775
|
-
- label: Critical
|
|
776
|
-
value: critical
|
|
777
|
-
color: "#7e22ce"
|
|
778
|
-
```
|
|
779
|
-
|
|
780
706
|
| Property | Type | Default | Description |
|
|
781
707
|
| --- | --- | --- | --- |
|
|
782
|
-
| `align` | string | `"start"` | Align options.
|
|
708
|
+
| `align` | string | `"start"` | Align options. Enum: `start`, `end`, `center`, `baseline`. |
|
|
783
709
|
| `color` | string | - | Selected checkbox color. |
|
|
784
|
-
| `columns` | integer \| object | - | Number of columns to lay the options out in, or a responsive breakpoint object. Use a count that divides 24 evenly. |
|
|
785
710
|
| `disabled` | boolean | `false` | Disable the block if true. |
|
|
786
|
-
| `direction` | string | `"horizontal"` | List options horizontally or vertical.
|
|
787
|
-
| `
|
|
788
|
-
| `wrap` | boolean | `true` | Specifies wrapping of options. Applies when 'direction' is 'horizontal'. Ignored when 'columns' is set. |
|
|
711
|
+
| `direction` | string | `"horizontal"` | List options horizontally or vertical. Enum: `horizontal`, `vertical`. |
|
|
712
|
+
| `wrap` | boolean | `true` | Specifies wrapping of options. Applies when 'direction' is 'horizontal'. |
|
|
789
713
|
| `options` | array | `[]` | Options can either be an array of primitive values, on an array of label, value pairs - supports html. |
|
|
790
714
|
| `options.$.label` | string | - | Value label shown to user - supports html. |
|
|
791
715
|
| `options.$.value` | string \| number \| boolean | - | Option value. |
|
|
@@ -822,7 +746,7 @@ Checkbox group for selecting multiple options.
|
|
|
822
746
|
| `theme.lineWidth` | number | `1` | Border width of the checkbox. |
|
|
823
747
|
| `theme.lineType` | string | `"solid"` | Border style of the checkbox. |
|
|
824
748
|
| `theme.fontSize` | number | `14` | Font size for checkbox labels. |
|
|
825
|
-
| `theme.marginXS` | number | `8` |
|
|
749
|
+
| `theme.marginXS` | number | `8` | Horizontal gap between checkboxes in a group. |
|
|
826
750
|
| `theme.paddingXS` | number | `8` | Inline padding between the checkbox and its label text. |
|
|
827
751
|
|
|
828
752
|
| Event | Event Data | Description |
|
|
@@ -752,75 +752,13 @@ Radio group for selecting a single option.
|
|
|
752
752
|
valueKey: id
|
|
753
753
|
```
|
|
754
754
|
|
|
755
|
-
```yaml
|
|
756
|
-
- id: radio_columns_two
|
|
757
|
-
type: RadioSelector
|
|
758
|
-
properties:
|
|
759
|
-
title: Two columns
|
|
760
|
-
columns: 2
|
|
761
|
-
options:
|
|
762
|
-
- Weekday mornings
|
|
763
|
-
- Weekday afternoons
|
|
764
|
-
- Weekday evenings
|
|
765
|
-
- Weekend mornings
|
|
766
|
-
- Weekend afternoons
|
|
767
|
-
- Weekend evenings
|
|
768
|
-
- id: radio_columns_responsive
|
|
769
|
-
type: RadioSelector
|
|
770
|
-
properties:
|
|
771
|
-
title: One column below md, three from md up
|
|
772
|
-
columns:
|
|
773
|
-
xs: 1
|
|
774
|
-
md: 3
|
|
775
|
-
options:
|
|
776
|
-
- Email
|
|
777
|
-
- SMS
|
|
778
|
-
- Push notification
|
|
779
|
-
- Webhook
|
|
780
|
-
- In-app message
|
|
781
|
-
- Weekly digest
|
|
782
|
-
- id: radio_columns_gutter
|
|
783
|
-
type: RadioSelector
|
|
784
|
-
properties:
|
|
785
|
-
title: Wider gutter
|
|
786
|
-
columns: 2
|
|
787
|
-
gutter:
|
|
788
|
-
- 24
|
|
789
|
-
- 12
|
|
790
|
-
options:
|
|
791
|
-
- Read only
|
|
792
|
-
- Read and write
|
|
793
|
-
- Administer
|
|
794
|
-
- No access
|
|
795
|
-
- id: radio_columns_per_option_color
|
|
796
|
-
type: RadioSelector
|
|
797
|
-
properties:
|
|
798
|
-
title: Coloured options in a grid
|
|
799
|
-
columns: 2
|
|
800
|
-
options:
|
|
801
|
-
- label: Low
|
|
802
|
-
value: low
|
|
803
|
-
color: "#16a34a"
|
|
804
|
-
- label: Medium
|
|
805
|
-
value: medium
|
|
806
|
-
color: "#d97706"
|
|
807
|
-
- label: High
|
|
808
|
-
value: high
|
|
809
|
-
color: "#dc2626"
|
|
810
|
-
- label: Critical
|
|
811
|
-
value: critical
|
|
812
|
-
color: "#7e22ce"
|
|
813
|
-
```
|
|
814
|
-
|
|
815
755
|
| Property | Type | Default | Description |
|
|
816
756
|
| --- | --- | --- | --- |
|
|
817
|
-
| `align` | string | `"start"` | Align options.
|
|
757
|
+
| `align` | string | `"start"` | Align options. Enum: `start`, `end`, `center`, `baseline`. |
|
|
818
758
|
| `color` | string | - | Selected radio color. |
|
|
819
|
-
| `columns` | integer \| object | - | Number of columns to lay the options out in, or a responsive breakpoint object. Use a count that divides 24 evenly. |
|
|
820
759
|
| `disabled` | boolean | `false` | Disable the block if true. |
|
|
821
|
-
| `direction` | string | `"horizontal"` | List options horizontally or vertical.
|
|
822
|
-
| `
|
|
823
|
-
| `wrap` | boolean | `true` | Specifies wrapping of options. Applies when 'direction' is 'horizontal'. Ignored when 'columns' is set. |
|
|
760
|
+
| `direction` | string | `"horizontal"` | List options horizontally or vertical. Enum: `horizontal`, `vertical`. |
|
|
761
|
+
| `wrap` | boolean | `true` | Specifies wrapping of options. Applies when 'direction' is 'horizontal'. |
|
|
824
762
|
| `label` | object | - | Label properties. |
|
|
825
763
|
| `label.align` | string | `"left"` | Align label left or right when inline. Enum: `left`, `right`. |
|
|
826
764
|
| `label.colon` | boolean | `true` | Append label with colon. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# S3UploadButton
|
|
2
2
|
|
|
3
|
-
__Deprecated__ — use the provider-neutral
|
|
3
|
+
__Deprecated__ — use the provider-neutral <a href="/Upload">Upload</a> block with `uploadPolicyRequestId` instead. S3UploadButton remains as an alias so existing apps keep working. Upload files to AWS S3 with a button trigger. Supports file type filtering, upload limits, and custom button styling. Requires an `AwsS3PresignedPostPolicy` request to define the S3 upload policy.
|
|
4
4
|
|
|
5
5
|
> The S3UploadButton requires an AwsS3Bucket connection and AwsS3PresignedPostPolicy request to upload files. The examples on this page demonstrate UI configuration only — uploads will not function without a configured S3 connection.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# S3UploadDragger
|
|
2
2
|
|
|
3
|
-
__Deprecated__ — use the provider-neutral
|
|
3
|
+
__Deprecated__ — use the provider-neutral <a href="/UploadDragger">UploadDragger</a> block with `uploadPolicyRequestId` instead. S3UploadDragger remains as an alias so existing apps keep working. Drag-and-drop file upload area for AWS S3. Supports file type filtering, upload limits, custom drag zone styling, and paste-to-upload. Requires an `AwsS3PresignedPostPolicy` request to define the S3 upload policy.
|
|
4
4
|
|
|
5
5
|
> The S3UploadDragger requires an AwsS3Bucket connection and AwsS3PresignedPostPolicy request to upload files. The examples on this page demonstrate UI configuration only — uploads will not function without a configured S3 connection.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# S3UploadPhoto
|
|
2
2
|
|
|
3
|
-
__Deprecated__ — use the provider-neutral
|
|
3
|
+
__Deprecated__ — use the provider-neutral <a href="/UploadPhoto">UploadPhoto</a> block with `uploadPolicyRequestId` instead. S3UploadPhoto remains as an alias so existing apps keep working. Picture-card style image upload for AWS S3. Displays a camera icon with upload text in a card format. Only accepts image files. Requires an `AwsS3PresignedPostPolicy` request to define the S3 upload policy.
|
|
4
4
|
|
|
5
5
|
> The S3UploadPhoto requires an AwsS3Bucket connection and AwsS3PresignedPostPolicy request to upload files. The examples on this page demonstrate UI configuration only — uploads will not function without a configured S3 connection.
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TiptapMentionInput
|
|
2
2
|
|
|
3
|
-
Rich-text editor with @-mention support. Same feature set as TiptapInput, plus a mention dropdown populated from a static options list or a request. Mention options can be marked as groups (roles, teams, queues) to render under their own menu section, as distinctly coloured chips, and with a hover popover listing the group
|
|
3
|
+
Rich-text editor with @-mention support. Same feature set as TiptapInput, plus a mention dropdown populated from a static options list or a request. Mention options can be marked as groups (roles, teams, queues) to render under their own menu section, as distinctly coloured chips, and with a hover popover listing the group's current members. See the guide below.
|
|
4
4
|
|
|
5
5
|
## Group mentions
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MasonryList
|
|
2
2
|
|
|
3
|
-
Masonry-style grid layout for list data. Items flow into columns and stack vertically, filling gaps left by shorter items. Provide an array in state and use _state operators in the template to access each item
|
|
3
|
+
Masonry-style grid layout for list data. Items flow into columns and stack vertically, filling gaps left by shorter items. Provide an array in state and use _state operators in the template to access each item's data.
|
|
4
4
|
|
|
5
5
|
```yaml
|
|
6
6
|
- id: ml_basic
|
|
@@ -29,7 +29,6 @@ The regex operator has shorthand argument definitions that can be used on web cl
|
|
|
29
29
|
- `null`
|
|
30
30
|
- `undefined`
|
|
31
31
|
- `none` (`null` or `undefined`)
|
|
32
|
-
- `empty` (`null`, `undefined`, `''`, or `[]` - note that `0`, `false` and `{}` are not empty)
|
|
33
32
|
- `primitive` (`undefined`, `null`, `string`, `number`, `boolean`, or `date`)
|
|
34
33
|
- `on: any`: The value to test. One of `on` or `key` must be specified unless the operator is used in an input block.
|
|
35
34
|
- `key: string`: The key of a value in `state` to test. One of `on` or `key` must be specified unless the operator is used in an input block.
|
|
@@ -61,23 +60,13 @@ Returns: `true` if a number.
|
|
|
61
60
|
id: input
|
|
62
61
|
type: TextInput
|
|
63
62
|
validate:
|
|
64
|
-
- message: This field
|
|
63
|
+
- message: This field id required.
|
|
65
64
|
status: error
|
|
66
65
|
pass:
|
|
67
66
|
_not:
|
|
68
|
-
_type:
|
|
67
|
+
_type: none
|
|
69
68
|
```
|
|
70
|
-
Returns: `true` if the input
|
|
71
|
-
|
|
72
|
-
###### Check if a value is empty:
|
|
73
|
-
```yaml
|
|
74
|
-
_type:
|
|
75
|
-
type: empty
|
|
76
|
-
on:
|
|
77
|
-
_state: selected_tags
|
|
78
|
-
```
|
|
79
|
-
Returns: `true` if `selected_tags` is `null`, `undefined`, `''` or `[]`, and `false` for any
|
|
80
|
-
other value, including `0`, `false` and `{}`.
|
|
69
|
+
Returns: `true` if the input is none.
|
|
81
70
|
|
|
82
71
|
###### Test if an id in the `urlQuery` is undefined or null:
|
|
83
72
|
```yaml
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
}): any
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
The `_user` operator gets a value from the [`user`](/user-object) object
|
|
13
|
+
The `_user` operator gets a value from the [`user`](/user-object) object. The `user` object contains the data in the user idToken if OpenID Connect authentication is configured and a user is logged in.
|
|
14
14
|
|
|
15
15
|
#### Arguments
|
|
16
16
|
|
|
@@ -50,7 +50,7 @@ Returns: The entire `user` object.
|
|
|
50
50
|
###### Dot notation:
|
|
51
51
|
Assuming user:
|
|
52
52
|
```yaml
|
|
53
|
-
|
|
53
|
+
sub: abc123
|
|
54
54
|
name: User Name
|
|
55
55
|
my_object:
|
|
56
56
|
subfield: 'Value'
|
|
@@ -76,7 +76,7 @@ Returns: The value of `might_not_exist`, or `"Default value"`.
|
|
|
76
76
|
###### Block list indices:
|
|
77
77
|
Assuming `user`:
|
|
78
78
|
```yaml
|
|
79
|
-
|
|
79
|
+
sub: abc123
|
|
80
80
|
name: User Name
|
|
81
81
|
my_array:
|
|
82
82
|
- value: 0
|
|
@@ -8,19 +8,15 @@ The `Login` action is used to start the user login flow. If only one OAuth provi
|
|
|
8
8
|
|
|
9
9
|
The authorization url usually hosts a page where the user can input their credentials. After the user has logged in successfully, the user is redirected to the `/api/auth/callback/<provider_id>` route in the Lowdefy app, where the rest of the authorization code flow is completed. This URL usually needs to be configured in the identity provider's settings.
|
|
10
10
|
|
|
11
|
-
The `callbackUrl`
|
|
12
|
-
|
|
13
|
-
In a protected app a signed-out visitor is sent to the sign-in page for every URL, present or absent, so a `404` means you are signed in — see [Page and API existence](/auth-upgrade#page-and-api-existence-is-no-longer-observable-before-you-sign-in).
|
|
14
|
-
|
|
15
|
-
To sign in without navigating at all - a login form in a modal, or an embedded panel - set `callbackUrl: false`. This is not valid for magic-link or social/OAuth sign-in, which redirect through a hop Lowdefy does not control.
|
|
11
|
+
The `callbackUrl` parameters of the Login action specify where the user is redirected after login is complete. If `callbackUrl` parameters not set, the user will return to the page from which the action was called.
|
|
16
12
|
|
|
17
13
|
The parameters are:
|
|
18
14
|
- `authUrl: object`:
|
|
19
15
|
- `urlQuery: object`: Query parameters to set for the authorization URL.
|
|
20
|
-
- `callbackUrl: object
|
|
16
|
+
- `callbackUrl: object`:
|
|
21
17
|
- `home: boolean`: Redirect to the home page after the login flow is complete.
|
|
22
18
|
- `pageId: string`: The pageId of the page to redirect to after the login flow is complete.
|
|
23
|
-
- `url: string`: The URL to redirect to after the login flow is complete.
|
|
19
|
+
- `url: string`: The URL to redirect to after the login flow is complete.
|
|
24
20
|
- `urlQuery: object`: The urlQuery to set for the page the user is redirected to after login.
|
|
25
21
|
- `providerId: string`: The ID of the provider that should be used for login. If not set and only one provider is configured the configured provider will be used. Else the user will be redirected to a sign in page where they can choose a provider.
|
|
26
22
|
|
|
@@ -95,164 +91,18 @@ events:
|
|
|
95
91
|
screen_hint: signup
|
|
96
92
|
```
|
|
97
93
|
|
|
98
|
-
## Magic link sign-in
|
|
99
|
-
|
|
100
|
-
`Login` with `magicLink: true` emails the user a sign-in link. By default that link points straight at Better Auth's verify endpoint, which consumes the single-use token on the first `GET` of the URL.
|
|
101
|
-
|
|
102
|
-
That is a problem in corporate inboxes. Mail security products — Microsoft Defender Safe Links, Proofpoint URL Defense, Mimecast — fetch every link in a message as it is delivered, so the scanner spends the token minutes before the person clicks, and the person lands on the error page with `INVALID_TOKEN`.
|
|
103
|
-
|
|
104
|
-
Set [`auth.authPages.magicLink`](/auth-configuration#auth-pages) to a page in your app to close that gap. The email then links to your page, carrying the token and the callback destinations on its URL query, and a [`MagicLinkVerify`](/MagicLinkVerify) action on a **button click** walks to the verify endpoint. Fetching the landing page does nothing, so a scanner cannot consume the token.
|
|
105
|
-
|
|
106
|
-
```yaml
|
|
107
|
-
lowdefy: {{ version }}
|
|
108
|
-
auth:
|
|
109
|
-
magicLink:
|
|
110
|
-
enabled: true
|
|
111
|
-
authPages:
|
|
112
|
-
magicLink: /magic-link
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
```yaml
|
|
116
|
-
id: magic-link
|
|
117
|
-
type: PageHeaderMenu
|
|
118
|
-
blocks:
|
|
119
|
-
- id: content
|
|
120
|
-
type: Box
|
|
121
|
-
blocks:
|
|
122
|
-
- id: title
|
|
123
|
-
type: Title
|
|
124
|
-
properties:
|
|
125
|
-
content: Sign in
|
|
126
|
-
level: 3
|
|
127
|
-
- id: description
|
|
128
|
-
type: Paragraph
|
|
129
|
-
properties:
|
|
130
|
-
content: Click the button below to finish signing in.
|
|
131
|
-
- id: verify_button
|
|
132
|
-
type: Button
|
|
133
|
-
properties:
|
|
134
|
-
title: Sign in
|
|
135
|
-
events:
|
|
136
|
-
onClick:
|
|
137
|
-
- id: verify
|
|
138
|
-
type: MagicLinkVerify
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
The landing page must be reachable while signed out, so add it to `auth.pages.public`.
|
|
142
|
-
|
|
143
|
-
Do **not** run `MagicLinkVerify` in the page's `onMount`, and do not auto-redirect to the verify endpoint. Some scanning sandboxes render the page and execute its JavaScript, so an automatic verify hands the token back to the scanner and you are no better off than linking at the endpoint directly. The whole protection is that a human has to click.
|
|
144
|
-
|
|
145
|
-
The action needs no parameters: the token and the `callbackURL`, `newUserCallbackURL` and `errorCallbackURL` values are read from the landing page's own URL query, which the email put there. Pass parameters only to override them.
|
|
146
|
-
|
|
147
|
-
## Email code sign-in
|
|
148
|
-
|
|
149
|
-
With `auth.emailOTP` enabled the app can sign a person in with a code emailed to them. Unlike a magic link, the code is typed into the tab they started from — so it survives corporate mail security that pre-fetches links (and consumes the single-use link token), and it works when the email is read on another device.
|
|
150
|
-
|
|
151
|
-
Two actions drive it:
|
|
152
|
-
|
|
153
|
-
- [`EmailOtpSend`](/EmailOtpSend) sends the code to an email address.
|
|
154
|
-
- [`EmailOtpVerify`](/EmailOtpVerify) signs the person in with the code they typed.
|
|
155
|
-
|
|
156
|
-
`EmailOtpVerify` lands the user through the same three sources as `Login`: the `callbackUrl` param, then the `?callbackUrl=` query, then the app's home page. `callbackUrl: false` verifies without navigating — it is a plain JSON sign-in with no redirect hop, so staying put is valid here.
|
|
157
|
-
|
|
158
|
-
### With magic link, one email carries both
|
|
159
|
-
|
|
160
|
-
When `auth.magicLink` is enabled alongside `auth.emailOTP`, the magic-link email also carries the code, so one email serves both paths. Keep using `Login` with `magicLink: true` to send it — no change is needed — and offer `EmailOtpVerify` on the same page for people whose link does not work. `EmailOtpSend` is then only needed for a code-only page, where no link is offered at all.
|
|
161
|
-
|
|
162
|
-
###### A sign-in page offering a code:
|
|
163
|
-
```yaml
|
|
164
|
-
id: email-code-login
|
|
165
|
-
type: Box
|
|
166
|
-
blocks:
|
|
167
|
-
- id: email
|
|
168
|
-
type: TextInput
|
|
169
|
-
required: true
|
|
170
|
-
properties:
|
|
171
|
-
title: Email
|
|
172
|
-
- id: send_code
|
|
173
|
-
type: Button
|
|
174
|
-
properties:
|
|
175
|
-
title: Send code
|
|
176
|
-
events:
|
|
177
|
-
onClick:
|
|
178
|
-
- id: validate
|
|
179
|
-
type: Validate
|
|
180
|
-
params:
|
|
181
|
-
regex: ^email$
|
|
182
|
-
- id: send
|
|
183
|
-
type: EmailOtpSend
|
|
184
|
-
params:
|
|
185
|
-
email:
|
|
186
|
-
_state: email
|
|
187
|
-
- id: sent
|
|
188
|
-
type: DisplayMessage
|
|
189
|
-
params:
|
|
190
|
-
content: Check your email for the sign-in code.
|
|
191
|
-
- id: otp
|
|
192
|
-
type: TextInput
|
|
193
|
-
properties:
|
|
194
|
-
title: Sign-in code
|
|
195
|
-
- id: sign_in
|
|
196
|
-
type: Button
|
|
197
|
-
properties:
|
|
198
|
-
title: Sign in
|
|
199
|
-
events:
|
|
200
|
-
onClick:
|
|
201
|
-
- id: verify
|
|
202
|
-
type: EmailOtpVerify
|
|
203
|
-
params:
|
|
204
|
-
email:
|
|
205
|
-
_state: email
|
|
206
|
-
otp:
|
|
207
|
-
_state: otp
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
An expired, mistyped or already-used code is the auth server rejecting the attempt, not an app fault: the action throws a `UserError`, so `onClick` `catch` actions run and the message displays, but nothing is reported to the server.
|
|
211
|
-
|
|
212
|
-
## SMS sign-in
|
|
213
|
-
|
|
214
|
-
`PhoneNumberVerify` completes a sign-in with an SMS code, and lands the user through the same three sources as `Login`: the `callbackUrl` param, then the `?callbackUrl=` query, then the app's home page. `callbackUrl: false` verifies without navigating.
|
|
215
|
-
|
|
216
|
-
Two modes are exempt, because neither ends with the user arriving somewhere new:
|
|
217
|
-
|
|
218
|
-
- `disableSession: true` creates no session to arrive with.
|
|
219
|
-
- `updatePhoneNumber: true` is a signed-in user confirming a new number. They already had a session, and the confirmation usually runs in a modal a navigation would yank them out of.
|
|
220
|
-
|
|
221
|
-
### Carrying the destination to a separate SMS form
|
|
222
|
-
|
|
223
|
-
The `?callbackUrl=` query is read from the page the action runs on, and the unauthenticated bounce puts it on `authPages.signIn`. If your SMS form lives on its own page, the link that gets the user there has to carry the parameter, or the destination falls back to the home page:
|
|
224
|
-
|
|
225
|
-
```yaml
|
|
226
|
-
- id: to_phone_login
|
|
227
|
-
type: Link
|
|
228
|
-
params:
|
|
229
|
-
pageId: phone-login
|
|
230
|
-
urlQuery:
|
|
231
|
-
_if:
|
|
232
|
-
test:
|
|
233
|
-
_eq:
|
|
234
|
-
- _url_query: callbackUrl
|
|
235
|
-
- null
|
|
236
|
-
then: null
|
|
237
|
-
else:
|
|
238
|
-
callbackUrl:
|
|
239
|
-
_url_query: callbackUrl
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
The `_if` is what keeps a user who reached the sign-in page directly from being sent to `/phone-login?callbackUrl=null` — `urlQuery` serialises a null value rather than dropping the key.
|
|
243
|
-
|
|
244
94
|
## Logout
|
|
245
95
|
|
|
246
96
|
When the `Logout` action is called, the user data and authorization cookies are cleared by the app.
|
|
247
97
|
|
|
248
|
-
The `callbackUrl`
|
|
98
|
+
The `callbackUrl` parameters of the Logout action specify where the user is redirected after logout is complete. If `callbackUrl` parameters are not set, the user will return to the page from which the action was called.
|
|
249
99
|
|
|
250
100
|
The parameters are:
|
|
251
101
|
- `callbackUrl: object`:
|
|
252
|
-
- `home: boolean`: Redirect to the home page after the
|
|
253
|
-
- `pageId: string`: The pageId of the page to redirect to after the
|
|
254
|
-
- `url: string`: The URL to redirect to after the
|
|
255
|
-
- `urlQuery: object`: The urlQuery to set for the page the user is redirected to after
|
|
102
|
+
- `home: boolean`: Redirect to the home page after the login flow is complete.
|
|
103
|
+
- `pageId: string`: The pageId of the page to redirect to after the login flow is complete.
|
|
104
|
+
- `url: string`: The URL to redirect to after the login flow is complete.
|
|
105
|
+
- `urlQuery: object`: The urlQuery to set for the page the user is redirected to after login.
|
|
256
106
|
- `redirect: boolean`: If set to `false` the user session will be cleared, but the page will not be reloaded.
|
|
257
107
|
|
|
258
108
|
|
|
@@ -29,11 +29,3 @@ The Login and Logout actions are used to start the login and logout processes.
|
|
|
29
29
|
## \_user operator
|
|
30
30
|
|
|
31
31
|
The `_user` operator can be used to access data in the user object received from the identity provider. The OpenID Connect standard claims (fields like `name` or `email`) are mapped to the user object by default and addition fields can be configured using the `userFields` configuration option.
|
|
32
|
-
|
|
33
|
-
### `two_factor_enrolled`
|
|
34
|
-
|
|
35
|
-
`_user: two_factor_enrolled` is `true` when the caller holds a factor that satisfies [`auth.twoFactor.required`](/two-factor) — a TOTP enrolment **or** a registered passkey.
|
|
36
|
-
|
|
37
|
-
It is a fact about the **user**, not the session: it does not assert that a factor was presented on this sign-in, only that the user has one on file. (The name is imperfect — a passkey is not literally a second factor. The field means precisely "holds a factor that satisfies `auth.twoFactor.required`", which a passkey does on its own.)
|
|
38
|
-
|
|
39
|
-
It is present only on session-resolved callers. The API strategy and the injected callers used in dev and e2e carry no session and so do not carry this field.
|