Skip to content

Commit dc04df0

Browse files
committed
Merge branch 'main' of github.com:devforth/adminforth into next
AdminForth/1731/security-audit AdminForth/1731/security-audit
2 parents 1c44fd4 + c624c4e commit dc04df0

27 files changed

Lines changed: 1073 additions & 131 deletions

File tree

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Add only non-sensitive production environment variables here so deployed applications can use them
22
# Deliver sensitive production environment variables via your deployment platform's process environment
33

4-
NODE_ENV=production
4+
NODE_ENV=production
5+
DEBUG_LEVEL=info
6+
AF_DEBUG_LEVEL=info
7+
DB_DEBUG_LEVEL=info

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const admin = new AdminForth({
1616
usernameField: 'email',
1717
passwordHashField: 'password_hash',
1818
rememberMeDuration: '30d',
19+
rateLimit: ['500/5m', '5000/1h', '10000/1d'],
1920
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',
2021
loginBackgroundPosition: '1/2',
2122
loginPromptHTML: async () => {

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,31 @@ new AdminForth({
3030
In this case users who will check "Remember me" checkbox will be logged in for 7 days instead of 24 hours.
3131
3232
33+
## Login rate limits
34+
35+
AdminForth rate-limits login attempts by client IP using `auth.rateLimit`. Password login, OAuth login, and passkey login use the same configured limits, but each login method has its own independent rate-limit bucket.
36+
37+
By default AdminForth uses:
38+
39+
```ts
40+
['500/5m', '5000/1h', '10000/1d']
41+
```
42+
43+
You can override it in the app config:
44+
45+
```ts ./index.ts
46+
new AdminForth({
47+
...
48+
auth: {
49+
rateLimit: ['10/5m', '100/1h', '500/1d']
50+
}
51+
})
52+
```
53+
54+
The format is `requests/period`, where period can use `s`, `m`, `h`, or `d`.
55+
Because rate limits are keyed by client IP, configure `auth.clientIpHeader` when AdminForth runs behind a trusted CDN or reverse proxy. See [Trusting client IP addresses](#trusting-client-ip-addresses).
56+
57+
3358
## Password strength
3459
3560
AdminForth allows to set validation RegExp based rules for any field. This can be reused for password strength validation.
@@ -284,4 +309,4 @@ This means that a user is allowed to make up to 20 requests within one day, and
284309
- h → hours (1h)
285310
- d → days (1d)
286311
287-
> ☝ Сonsume(key) is used to check whether a specific key such as a userId, IP address, or any other identifier has exceeded its allowed request limit. If the limit has not been reached, it returns true, meaning the request is allowed to proceed.
312+
> ☝ Сonsume(key) is used to check whether a specific key such as a userId, IP address, or any other identifier has exceeded its allowed request limit. If the limit has not been reached, it returns true, meaning the request is allowed to proceed.

adminforth/documentation/docs/tutorial/06-Adapters/04-storage-adapters.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ R2_BUCKET_REGION=auto
5656
region: process.env.R2_BUCKET_REGION as string,
5757
s3ACL: "private",
5858
cleanupKeyValueAdapter: new LevelDBKeyValueAdapter({
59-
dbPath: './stores/cloudflare_r2_storage_keys',
60-
}),
59+
// ensure /stores/ folder is a persisted/backed up point, if you running in docker ensure ensure you mount /stores/ as volume
60+
dbPath: process.env.NODE_ENV === production ? '/stores/cloudflare_r2_storage_keys' : './cloudflare_r2_storage_keys',
61+
});,
6162
forcePathStyle: true,
6263
cleanupCheckInterval: '30m',
6364
cleanupGracePeriod: '5d'
@@ -88,7 +89,8 @@ R2_BUCKET_REGION=auto
8889
region: 'us-east-1',
8990
s3ACL: 'private',
9091
cleanupKeyValueAdapter: new LevelDBKeyValueAdapter({
91-
dbPath: './stores/minio_storage_keys',
92+
// ensure /stores/ folder is a persisted/backed up point, if you running in docker ensure ensure you mount /stores/ as volume
93+
dbPath: process.env.NODE_ENV === production ? '/stores/minio_storage_keys' : './minio_storage_keys',
9294
}),
9395
forcePathStyle: true,
9496
cleanupCheckInterval: '30m',

adminforth/documentation/docs/tutorial/06-Adapters/07-key-value-adapters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Redis uses in-memory storage with $O(1)$ get complexity. It is a great fit for l
3636
import RedisKeyValueAdapter from '@adminforth/key-value-adapter-redis';
3737

3838
const adapter = new RedisKeyValueAdapter({
39-
redisUrl: '127.0.0.1:6379',
39+
redisUrl: 'redis://localhost:6379',
4040
});
4141

4242
adapter.set('test-key', 'test-value', 120);

adminforth/documentation/docs/tutorial/09-Plugins/07-email-password-reset.md

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ Plugin allows to reset password for admin users who forgot their password by sen
1616
Installation:
1717

1818
```bash
19-
pnpm install @adminforth/email-password-reset --save
20-
pnpm install @adminforth/email-adapter-aws-ses --save
19+
pnpm add @adminforth/email-password-reset
20+
pnpm add @adminforth/email-adapter-aws-ses
21+
pnpm add @adminforth/key-value-adapter-ram
2122
```
2223

24+
>⚠️Note: we use key/value adapter to store used password reset token for validity period and we recomend to use stateful adapter like Redis in production, because stateless adapter (like key/value RAM) is cleared after server restart and password reset token could be re-used for the second time
25+
2326
Import plugin:
2427

2528
```typescript
@@ -42,6 +45,8 @@ Add plugin to user resource:
4245
```typescript ./resources/adminuser.ts
4346
import EmailResetPasswordPlugin from '@adminforth/email-password-reset';
4447
import EmailAdapterAwsSes from '@adminforth/email-adapter-aws-ses';
48+
import KeyValueAdapterRam from '@adminforth/key-value-adapter-ram';
49+
4550
...
4651
plugins: [
4752
...
@@ -56,12 +61,12 @@ plugins: [
5661
sendFrom: 'no-reply@devforth.io',
5762

5863
adapter: new EmailAdapterAwsSes({
59-
// region where SES is setup
60-
region: "eu-central-1",
61-
accessKeyId: process.env.AWS_ACCESS_KEY_ID as string,
62-
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string,
63-
}),
64-
64+
// region where SES is setup
65+
region: "eu-central-1",
66+
accessKeyId: process.env.AWS_ACCESS_KEY_ID as string,
67+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string,
68+
}),
69+
userResetTokensKeyValueAdapter: new KeyValueAdapterRam(),
6570
}),
6671
]
6772
```
@@ -102,12 +107,12 @@ plugins: [
102107
sendFrom: 'no-reply@devforth.io',
103108

104109
adapter: new EmailAdapterMailgun({
105-
apiKey: process.env.MAILGUN_API_KEY as string,
106-
domain: process.env.MAILGUN_DOMAIN as string,
107-
//baseUrl is optional, if not provided, will default to "https://api.mailgun.net" but if you are using Mailgun EU, you should use "https://api.eu.mailgun.net" instead
108-
baseUrl: process.env.MAILGUN_REGION_URL as string,
109-
}),
110-
110+
apiKey: process.env.MAILGUN_API_KEY as string,
111+
domain: process.env.MAILGUN_DOMAIN as string,
112+
//baseUrl is optional, if not provided, will default to "https://api.mailgun.net" but if you are using Mailgun EU, you should use "https://api.eu.mailgun.net" instead
113+
baseUrl: process.env.MAILGUN_REGION_URL as string,
114+
}),
115+
userResetTokensKeyValueAdapter: new KeyValueAdapterRam(),
111116
}),
112117
]
113118
```

adminforth/documentation/docs/tutorial/09-Plugins/23-background-jobs.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ BackgroundJobsPlugin adds a durable background job system to AdminForth. Jobs ar
99

1010

1111
## Setup
12-
12+
> ‼️ Note, that before deploying this plugin, you should create volume for the level db and pass is as `levelDbPath` param, so background jobs will be saved between redeploys
1313
First, install the plugin:
1414
```bash
1515
pnpm i @adminforth/background-jobs
@@ -124,6 +124,7 @@ export default {
124124
statusField: 'status',
125125
nameField: 'name',
126126
jobHandlerField: 'job_handler_name',
127+
levelDbPath: process.env.NODE_ENV === production ? '/stores/background_job_plugin' : './background_jobs',
127128
})
128129
]
129130
} as AdminForthResourceInput;

0 commit comments

Comments
 (0)