Skip to content

Commit d53608c

Browse files
committed
Merge branch 'main' of github.com:avo-hq/docs.avohq.io
2 parents 8c0da87 + 53ebba4 commit d53608c

13 files changed

+359
-11
lines changed

docs/3.0/authorization.md

+100-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ Controls whether the user can see the [records reordering](./records-reordering)
116116

117117
<Option name="`search?`">
118118

119-
Controls whether the user can see the global search input or the [resource search input](./search) on top of the <Index /> page.
119+
Controls whether the user can see the [resource search input](./search) on top of the <Index /> page.
120120
</Option>
121121

122122
## Associations
@@ -541,6 +541,105 @@ end
541541
```
542542
</Option>
543543

544+
## Explicit authorization
545+
546+
<Option name="`explicit_authorization`">
547+
548+
:::warning Option Renamed
549+
In versions between <Version version="3.13.4" /> and <Version version="3.13.6" />, this option is named `implicit_authorization`.
550+
:::
551+
552+
<VersionReq version="3.13.4" />
553+
554+
This option gives you control over how missing policy classes or methods are handled during authorization checks in your Avo application.
555+
556+
### Possible values
557+
558+
**`true`**
559+
- If a policy class or method is **missing** for a given resource or action, that action will automatically be considered **unauthorized**.
560+
- This behavior enhances security by ensuring that any unconfigured or unhandled actions are denied by default.
561+
562+
**`false`**
563+
- If a policy class or method is **missing**, the action will be considered **authorized** by default.
564+
565+
**`Proc`**
566+
- You can also set `explicit_authorization` as a `Proc` to apply custom logic. Within this block, you gain access to all attributes of [`Avo::ExecutionContext`](execution-context)
567+
568+
For example:
569+
570+
```ruby
571+
config.explicit_authorization = -> {
572+
current_user.access_to_admin_panel? && !current_user.admin?
573+
}
574+
```
575+
576+
In this case, missing policies will be handled based on the condition: if the user has access to the admin panel but isn't an admin, the `explicit_authorization` will be enabled. This option allows you to customize authorization decisions based on the context of the current user or other factors.
577+
### Default
578+
579+
- For **new applications** (starting from Avo `3.13.4`) the default value for `explicit_authorization` is `true`. This provides a more secure out-of-the-box experience by ensuring actions without explicit authorization are denied.
580+
581+
- For **existing applications** upgrading to `3.13.4` or later the default value for `explicit_authorization` remains `false` to preserve backward compatibility. Existing applications will retain the permissive behavior unless explicitly changed.
582+
583+
### Configuration:
584+
585+
You can configure this setting in your `config/avo.rb` file:
586+
587+
```ruby{4}
588+
Avo.configure do |config|
589+
# Set to true to deny access when policies or methods are missing
590+
# Set to false to allow access when policies or methods are missing
591+
config.explicit_authorization = true
592+
end
593+
```
594+
595+
### Examples:
596+
597+
1. **When `explicit_authorization` is `true`**
598+
- **Scenario**: You have a `Post` resource, but there is no policy class defined for it.
599+
- **Result**: All actions for the `Post` resource (index, show, create, etc.) will be **unauthorized** unless you explicitly define a policy class and methods for those actions.
600+
601+
---
602+
- **Scenario**: You have a `Post` resource, and the policy class defined for it only defines the `show?` method.
603+
604+
```ruby
605+
class PostPolicy < ApplicationPolicy
606+
def show?
607+
user.admin?
608+
end
609+
end
610+
```
611+
- **Result**: In this case, since the `PostPolicy` lacks an `index?` method, attempting to access the `index` action will be denied by default.
612+
613+
2. **When `explicit_authorization: false`**
614+
- **Scenario**: Same `Post` resource without a policy class.
615+
- **Result**: All actions for the `Post` resource will be **authorized** even though there are no explicit policy methods. This could expose unintended behavior, as any unprotected action will be accessible.
616+
617+
---
618+
619+
- **Scenario**: You have a `Post` resource, and the policy class defined for it only defines the `show?` method.
620+
```ruby
621+
class PostPolicy < ApplicationPolicy
622+
def show?
623+
user.admin?
624+
end
625+
end
626+
```
627+
- **Result**: In this case, missing methods like `index?` will allow access to the `index` action by default.
628+
629+
630+
### Migration Recommendations:
631+
632+
- **For applications after from Avo `3.13.4`**
633+
634+
It is recommended to leave `explicit_authorization` set to `true`, ensuring all actions must be explicitly authorized to prevent unintentional access.
635+
636+
- **For applications before from Avo `3.13.4`**
637+
638+
- If upgrading from an earlier version, carefully review your policies before enabling `explicit_authorization`. Missing policy methods that were previously allowing access will now deny access unless explicitly defined.
639+
640+
- It’s recommended to disable [`raise_error_on_missing_policy`](authorization.html#raise-errors-when-policies-are-missing) in production, though it's not mandatory. When `explicit_authorization` is set to `true`, the default behavior is to deny access for actions without a defined policy. In this case, it’s often better to show an unauthorized message to users rather than raise an error. However, keeping [`raise_error_on_missing_policy`](authorization.html#raise-errors-when-policies-are-missing) enabled in development can be helpful for identifying missing policy classes.
641+
</Option>
642+
544643
## Rolify integration
545644

546645
Check out [this guide](guides/rolify-integration.md) to add rolify role management with Avo.

docs/3.0/cards.md

+14
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,20 @@ end
199199

200200
<Image src="/assets/img/dashboards/prefix-suffix.jpg" width="651" height="168" alt="Avo Prefix & suffix" />
201201

202+
<br>
203+
204+
<VersionReq version="3.13" /> `prefix` and `suffix` became callable options.
205+
206+
The blocks are executed using [`Avo::ExecutionContext`](execution-context). Within this blocks, you gain access to all attributes of [`Avo::ExecutionContext`](execution-context) along with the `parent`.
207+
208+
```ruby{3,4}
209+
class Avo::Cards::UsersMetric < Avo::Cards::MetricCard
210+
self.id = 'users_metric'
211+
self.prefix = -> { params[:prefix] || parent.prefix }
212+
self.suffix = -> { params[:suffix] || parent.suffix }
213+
end
214+
```
215+
202216
## Chartkick card
203217

204218
A picture is worth a thousand words. So maybe a chart a hundred? Who knows? But creating charts in Avo is very easy with the help of the [chartkick](https://github.com/ankane/chartkick) gem.

docs/3.0/common/associations_scope_option_common.md

+4
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ field :user,
1414
```
1515

1616
Pass in a block where you attach scopes to the `query` object. The block gets executed in the [`ExecutionContext`](./../execution-context).
17+
18+
With version 2.5.0, you'll also have access to the `parent` record so that you can use that to scope your associated models even better.
19+
20+
Starting with version 3.12, access to `resource` and `parent_resource` was additionally provided.
1721
</Option>

docs/3.0/common/scopes_common.md

+2
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ The `comments` query on the user `Index` page will have the `approved` scope att
3131

3232
With version 2.5.0, you'll also have access to the `parent` record so that you can use that to scope your associated models even better.
3333

34+
Starting with version 3.12, access to `resource` and `parent_resource` was additionally provided.
35+
3436
All the `has_many` associations have the [`attach_scope`](./../associations/belongs_to#attach-scope) option available too.

docs/3.0/customization.md

+20-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ That will render all `id` fields in the **Index** view as a link to that resourc
7373

7474
<Image src="/assets/img/fields-reference/as-link-to-resource.jpg" width="694" height="166" alt="As link to resource" />
7575

76-
## Resource controls on the left side
76+
## Resource controls on the left or both sides
7777
<DemoVideo demo-video="https://youtu.be/MfryUtcXqvU?t=706" />
7878

7979
By default, the resource controls are located on the right side of the record rows, which might be hidden if there are a lot of columns. You might want to move the controls to the left side in that situation using the `resource_controls_placement` option.
@@ -84,9 +84,18 @@ Avo.configure do |config|
8484
end
8585
```
8686

87-
8887
<Image src="/assets/img/customization/resource-controls-left.jpg" width="1206" height="920" alt="Resource controls on the left side" />
8988

89+
<VersionReq version="3.13.7" class="mt-2" />
90+
91+
You might want to render the controls on both sides
92+
93+
```ruby{2}
94+
Avo.configure do |config|
95+
config.resource_controls_placement = :both
96+
end
97+
```
98+
9099
## Container width
91100

92101
```ruby{2-3}
@@ -397,6 +406,15 @@ Avo.configure do |config|
397406
end
398407
```
399408

409+
<VersionReq version="3.13.5" /> `disabled_features` become callable. Within this block, you gain access to all attributes of [`Avo::ExecutionContext`](execution-context)
410+
411+
```ruby{3}
412+
# config/initializers/avo.rb
413+
Avo.configure do |config|
414+
config.disabled_features = -> { current_user.is_admin? ? [] : [:global_search] }
415+
end
416+
```
417+
400418
After this setting, the global search will be hidden for users.
401419

402420
Supported options:

docs/3.0/dynamic-filters.md

+82
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,88 @@ dynamic_filter :tags,
591591

592592
</Option>
593593

594+
<Option name="`fetch_values_from`">
595+
596+
<VersionReq version="3.13" />
597+
598+
:::warning
599+
This option is compatible **only** with `tags` filters.
600+
:::
601+
602+
In some cases, you may need to retrieve values dynamically from an API. The `fetch_values_from` option allows you to provide a URL from which the filter will suggest values, functioning similarly to the `fetch_values_from` option in the tags field.
603+
604+
When a user searches for a record, the filter's input will send a request to the server to fetch records that match the query.
605+
606+
##### Default value
607+
608+
`nil`
609+
610+
:::info
611+
If you're using a `filterable` field the `fetch_values_from` are fetched from the field.
612+
613+
```ruby
614+
field :tags, as: :tags,
615+
fetch_values_from: -> { "/avo-filters/resources/cities/tags" }
616+
filterable: true
617+
```
618+
:::
619+
620+
#### Possible values
621+
622+
- String
623+
```ruby
624+
fetch_values_from: "/avo-filters/resources/cities/tags"
625+
```
626+
627+
- Proc that evaluates to a string.
628+
```ruby
629+
fetch_values_from: -> { "/avo-filters/resources/cities/tags" }
630+
```
631+
632+
The string should resolve to an endpoint that returns an array of objects with the keys `value`, `label` and optionally `avatar`.
633+
634+
::: code-group
635+
```ruby{3-19} [app/controllers/avo/skills_controller.rb]
636+
class Avo::CitiesController < Avo::ResourcesController
637+
def tags
638+
render json: [
639+
{
640+
value: 1,
641+
label: "one",
642+
avatar: "https://images.unsplash.com/photo-1560363199-a1264d4ea5fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&w=256&h=256&fit=crop"
643+
},
644+
{
645+
value: 2,
646+
label: "two",
647+
avatar: "https://images.unsplash.com/photo-1567254790685-6b6d6abe4689?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&w=256&h=256&fit=crop"
648+
},
649+
{
650+
value: 3,
651+
label: "three",
652+
avatar: "https://images.unsplash.com/photo-1560765447-da05a55e72f8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&w=256&h=256&fit=crop"
653+
}
654+
]
655+
end
656+
end
657+
```
658+
659+
```ruby{5-11} [config/routes.rb]
660+
Rails.application.routes.draw do
661+
# your routes...
662+
end
663+
664+
if defined? ::Avo
665+
Avo::Engine.routes.draw do
666+
scope :resources do
667+
get "cities/tags", to: "cities#tags"
668+
end
669+
end
670+
end
671+
```
672+
:::
673+
674+
</Option>
675+
594676
<Option name="`options`">
595677
<VersionReq version="3.10.10" />
596678

docs/3.0/fields/password.md

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ The `Password` field renders a `input[type="password"]` element for that field.
1111
field :password, as: :password
1212
```
1313

14+
#### Revealable
15+
16+
<VersionReq version="3.13.7" class="mt-2" />
17+
18+
You can set the `revealable` to true to show an "eye" icon that toggles the password between hidden or visible.
19+
1420
**Related:**
1521
- [Devise password optional](./../resources#devise-password-optional)
1622

docs/3.0/fields/tags.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ When the user searches for a record, the field will perform a request to the ser
242242

243243
#### Possible values
244244

245-
Valid values are `nil`, a string, or a block that evaluates to a string. The string should resolve to an enddpoint that returns an array of objects with the keys `value` and `label`.
245+
Valid values are `nil`, a string, or a block that evaluates to a string. The string should resolve to an endpoint that returns an array of objects with the keys `value` and `label`.
246246

247247
::: code-group
248248

docs/3.0/fields/trix.md

+15-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ field :body, as: :trix
1212

1313
The `Trix` field renders a [WYSIWYG Editor](https://trix-editor.org/) and can be associated with a `string` or `text` column in the database. The value stored in the database will be the editor's resulting `HTML` content.
1414

15-
1615
<Image src="/assets/img/fields/trix.jpg" width="877" height="193" alt="Trix field" />
1716

1817
Trix field is hidden from the `Index` view.
@@ -61,7 +60,6 @@ Enables file attachments.
6160
`nil`, or a symbol representing the `has_many_attachments` key on the model.
6261
</Option>
6362

64-
6563
## File attachments
6664

6765
<!-- @include: ./../common/files_gem_common.md-->
@@ -105,3 +103,18 @@ Trix integrates seamlessly with Action Text. It will automatically work with Act
105103
## Demo app
106104

107105
We prepared a [demo](https://trix.avodemo.com/) to showcase Trix's abilities to work with Action Text and Active Storage.
106+
107+
## Javascript Alert Messages
108+
109+
<VersionReq version="3.13.8" />
110+
111+
You can customize the javascript alert messages for various actions in the Trix editor. Below are the default messages that can be translated or modified:
112+
113+
```yml
114+
avo:
115+
this_field_has_attachments_disabled: This field has attachments disabled.
116+
you_cant_upload_new_resource: You can't upload files into the Trix editor until you save the resource.
117+
you_havent_set_attachment_key: You haven't set an `attachment_key` to this Trix field.
118+
```
119+
120+
Refer to the [default](https://github.com/avo-hq/avo/blob/main/lib/generators/avo/templates/locales/avo.en.yml) for more details.

0 commit comments

Comments
 (0)