Skip to content

Commit 5dba4ae

Browse files
committed
Merge branch 'next' of github.com:devforth/adminforth into next
2 parents 14c80f8 + 36c0bbb commit 5dba4ae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2324
-559
lines changed

adminforth/commands/createApp/templates/index.ts.hbs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import AdminForth from 'adminforth';
33
import usersResource from "./resources/adminuser.js";
44
import { fileURLToPath } from 'url';
55
import path from 'path';
6+
import { Filters } from 'adminforth';
67

78
const ADMIN_BASE_URL = '';
89

@@ -15,6 +16,12 @@ export const admin = new AdminForth({
1516
rememberMeDays: 30,
1617
loginBackgroundImage: 'https://images.unsplash.com/photo-1534239697798-120952b76f2b?q=80&w=3389&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
1718
loginBackgroundPosition: '1/2',
19+
loginPromptHTML: async () => {
20+
const adminforthUserExists = await admin.resource("adminuser").count(Filters.EQ('email', 'adminforth')) > 0;
21+
if (adminforthUserExists) {
22+
return "Please use <b>adminforth</b> as username and <b>adminforth</b> as password"
23+
}
24+
},
1825
},
1926
customization: {
2027
brandName: "{{appName}}",

adminforth/commands/createCustomComponent/configLoader.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import fs from 'fs/promises';
22
import path from 'path';
33
import chalk from 'chalk';
44
import jiti from 'jiti';
5+
import dotenv from "dotenv";
56

7+
dotenv.config({ path: '.env.local', override: true });
8+
dotenv.config({ path: '.env', override: true });
69

710
export async function loadAdminForthConfig() {
811
const configFileName = 'index.ts';

adminforth/documentation/blog/2024-10-01-ai-blog/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Go to bucket settings, Permissions, Object ownership and select "ACLs Enabled" a
7272
"*"
7373
],
7474
"AllowedMethods": [
75+
"HEAD",
7576
"PUT"
7677
],
7778
"AllowedOrigins": [

adminforth/documentation/docs/tutorial/03-Customization/03-virtualColumns.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -235,21 +235,4 @@ Hook still has access to the virtual field `updates.password`, and we use built-
235235
After hook is executed, `updates.password` will be removed from the record since it is virtual, so password itself will not be saved to the database.
236236
237237
238-
### Backend-only fields
239-
240-
Another important point is that `hashed_password` field should never be passed to frontend due to security reasons.
241-
242-
To do it we have 2 options:
243-
244-
1) Do not list `password_hash` in the `columns` array of the resource. If AdminForth knows nothing about field
245-
it will never pass this field to frontend.
246-
2) Define `password_hash` in columns way but set `backendOnly`. The scond option is more explicit and should be preferrred
247-
248-
```ts
249-
{
250-
name: 'password_hash',
251-
type: AdminForthDataTypes.STRING,
252-
showIn: { all: false },
253-
backendOnly: true, // will never go to frontend
254-
}
255-
```
238+

adminforth/documentation/docs/tutorial/03-Customization/06-customPages.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,14 @@ Open `index.ts` file and add the following code *BEFORE* `admin.express.serve(`
306306
307307
```ts title="/index.ts"
308308
309+
import type { IAdminUserExpressRequest } from 'adminforth';
310+
import express from 'express';
311+
309312
....
310313
311314
app.get(`${ADMIN_BASE_URL}/api/dashboard/`,
312315
admin.express.authorize(
313-
async (req:any, res:any) => {
316+
async (req:IAdminUserExpressRequest, res: express.Response) => {
314317
const days = req.body.days || 7;
315318
const apartsByDays = admin.resource('aparts').dataConnector.client.prepare(
316319
`SELECT

adminforth/documentation/docs/tutorial/03-Customization/08-pageInjections.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,14 @@ Now create file `ApartsPie.vue` in the `custom` folder of your project:
9898
Also we have to add an Api to get percentages:
9999
100100
```ts title="./index.ts"
101+
import type { IAdminUserExpressRequest } from 'adminforth';
102+
import express from 'express';
103+
104+
....
105+
101106
app.get(`${ADMIN_BASE_URL}/api/aparts-by-room-percentages/`,
102107
admin.express.authorize(
103-
async (req, res) => {
108+
async (req: IAdminUserExpressRequest, res: express.Response) => {
104109
const roomPercentages = await admin.resource('aparts').dataConnector.client.prepare(
105110
`SELECT
106111
number_of_rooms,

adminforth/documentation/docs/tutorial/03-Customization/09-Actions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ To implement this limitation use `allowed`:
9595
If you want to prohibit the use of bulk action for user, you can do it this way:
9696

9797
```ts title="./resources/apartments.ts"
98+
import { admin } from '../index';
99+
100+
....
101+
98102
bulkActions: [
99103
{
100104
label: 'Mark as listed',

adminforth/documentation/docs/tutorial/03-Customization/12-security.md

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,72 @@ server {
140140
proxy_set_header X-Forwarded-For $remote_addr;
141141
}
142142
}
143-
```
143+
```
144+
145+
146+
147+
### Backend-only fields
148+
149+
Some fields should never be accessed on frontend. For example, `hashed_password` field which is always created using CLI initial app, should never be passed to frontend due to security reasons.
150+
If any user of system can read `hashed_password` of another user, it can lead to account compromise.
151+
152+
To eliminate it we have 2 options:
153+
154+
1) Do not list `password_hash` in the `columns` array of the resource. If AdminForth knows nothing about field
155+
it will never pass this field to frontend!
156+
2) Define `password_hash` in columns way but set `backendOnly`.
157+
158+
The second option is more explicit and should be preferred. This option is used by default in CLI-bootstrapped projects:
159+
160+
```ts
161+
{
162+
name: 'password_hash',
163+
type: AdminForthDataTypes.STRING,
164+
showIn: { all: false },
165+
backendOnly: true, // will never go to frontend
166+
}
167+
```
168+
169+
#### Dynamically hide fields depending on user ACL / role
170+
171+
You can use `column.showIn` to show or hide column for user depending on his role.
172+
173+
However even if `showIn` value (or value returned by showIn function) is `false`, record value will still go to frontend and will be
174+
visible in the Network tab, so advanced user can still access field value. We did it in this way to provide AdminForth developers with ability to quickly use any record field in custom components.
175+
176+
However if you need securely hide only certain fields depending on role, you should use `column.backendOnly` and pass function there.
177+
178+
Let's consider example:
179+
180+
```ts
181+
{
182+
name: 'email',
183+
type: AdminForthDataTypes.STRING,
184+
showIn: {
185+
//diff-add
186+
all: false,
187+
//diff-add
188+
list: ({ adminUser }: { adminUser: AdminUser }) => adminUser.dbUser.role === 'superadmin',
189+
},
190+
}
191+
```
192+
193+
So if you will configure the email column in user resource like this, only superadmin will be able to see emails, and only in the list view.
194+
However, the email will still be present in the record and can be accessed by advanced users through the Network tab.
195+
196+
So to completely hide the email field from all users apart superadmins, you should use `column.backendOnly` and pass a function there.
197+
198+
```ts
199+
{
200+
name: 'email',
201+
type: AdminForthDataTypes.STRING,
202+
//diff-add
203+
backendOnly: ({ adminUser }: { adminUser: AdminUser }) => adminUser.dbUser.role === 'superadmin',
204+
showIn: {
205+
all: false,
206+
list: ({ adminUser }: { adminUser: AdminUser }) => adminUser.dbUser.role === 'superadmin',
207+
},
208+
}
209+
```
210+
211+
So if you will configure the email column in user resource like this, only superadmin will be able to see emails, and only in the list view.

adminforth/documentation/docs/tutorial/03-Customization/15-afcl.md

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,31 @@ const enable = ref(false)
362362
</div>
363363
</div>
364364

365+
366+
## Toggle
367+
368+
<div class="split-screen" >
369+
<div >
370+
371+
```ts
372+
import Toggle from '@/afcl/Toggle.vue';
373+
```
374+
375+
376+
```html
377+
<Toggle
378+
:disabled="false"
379+
@update:modelValue="toggleSwitchHandler">
380+
<p>Click me</p>
381+
</Toggle>
382+
```
383+
</div>
384+
<div>
385+
![AFCL Checkbox](image-94.png)
386+
</div>
387+
</div>
388+
389+
365390
## Dialog (Pop-up)
366391

367392
<div class="split-screen" >
@@ -1758,8 +1783,34 @@ import { JsonViever } from '@/afcl'
17581783
```
17591784
</div>
17601785
<div>
1761-
![Mixed Chart](image-93.png)
1786+
![JSON Viewer](image-93.png)
17621787
</div>
17631788
</div>
17641789

1790+
## Date picker
1791+
1792+
```ts
1793+
import { DatePicker } from '@/afcl';
1794+
const datePickerValue = ref()
1795+
```
1796+
1797+
### Basic
1798+
<div class="split-screen" >
1799+
1800+
<div>
1801+
```html
1802+
<DatePicker
1803+
v-model:datePickerValue="datePickerValue"
1804+
:column="{ type: 'datetime' }"
1805+
label="Pick start"
1806+
/>
1807+
```
1808+
</div>
1809+
<div>
1810+
![Date Picker](image-95.png)
1811+
</div>
1812+
</div>
1813+
1814+
1815+
17651816

19.7 KB
Loading

0 commit comments

Comments
 (0)