Skip to content

Commit d62aae2

Browse files
merge branch v2 (release 2.0.0-beta.38)
2 parents c24eb96 + 2493fde commit d62aae2

41 files changed

Lines changed: 643 additions & 131 deletions

Some content is hidden

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

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/automad/.wizard-completed
12
/automad/legacy
23
/automad/src/client/blocks/legacy
34
/automad/tests/main/config

CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
# Changelog
22

3-
## [v2.0.0-beta.37](https://github.com/marcantondahmen/automad/commit/8c19c19fedd220cea58d9a1f98f7d51a84a988bc)
3+
## [v2.0.0-beta.38](https://github.com/marcantondahmen/automad/commit/6fea03e6f009b332a65f620bf727ae25db8576b6)
44

5-
Tue, 2 Jun 2026 21:59:07 +0200
5+
Sat, 6 Jun 2026 21:44:32 +0200
6+
7+
### New Features
8+
9+
- add setup wizard for new installations and after system updates ([9be052c4c](https://github.com/marcantondahmen/automad/commit/9be052c4ca7697a42725b22ffdb366d2aa639bff))
10+
- include + into regex for valid email addresses ([fafec3c71](https://github.com/marcantondahmen/automad/commit/fafec3c718c01f9d64d00a20e4747fbb19b600fc))
11+
- update standard-lite theme ([6fea03e6f](https://github.com/marcantondahmen/automad/commit/6fea03e6f009b332a65f620bf727ae25db8576b6))
12+
13+
## [v2.0.0-beta.37](https://github.com/marcantondahmen/automad/commit/c24eb96ee1c9743d568e33a376dea2263af5c22a)
14+
15+
Tue, 2 Jun 2026 22:01:05 +0200
616

717
### Bugfixes
818

SECURITY.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,17 @@ After successfully being authenticated, the _username_ and a _csrf token_ will b
4141

4242
### Implications for Security
4343

44-
In order to fully understand possible attack vectors and the severity of reported vulnerabilities, one has to take the architectural concept, the way sessions work in Automad and the limitation of the visitor role into account. Generally, vulnerabilities can be broken down into two categories — _XSS (cross-site-scripting)_ and _CSRF (cross-site-request-forgery)_.
44+
In order to fully understand possible attack vectors and the severity of reported vulnerabilities, one has to take the architectural concept, the way sessions work in Automad and the distinction between visitors and admins into account. In particular, it is important to understand which actions are available to visitors, which actions require administrative privileges and where actual security boundaries exist.
45+
46+
#### Administrative Capabilities
47+
48+
Admins are fully trusted users that are granted complete control over an Automad installation by design. Among other things, admins can create and modify content, change configuration, install Composer packages, install and modify templates, deploy extensions and execute arbitrary PHP and JavaScript code as part of normal site development and maintenance workflows.
49+
50+
As a consequence, reports that require authenticated admin access and only demonstrate actions that could already be performed through custom templates, extensions, Composer packages, arbitrary PHP code or other administrative capabilities are generally not considered security vulnerabilities.
51+
52+
Such reports do not constitute privilege escalation, authentication bypass, unauthorized access or a security boundary violation. To be considered a security vulnerability, a report must demonstrate that an attacker can gain capabilities beyond those already granted to an authenticated admin or affect visitors without administrative privileges.
53+
54+
Please make sure that you understand Automad's architecture and security model before submitting a report.
4555

4656
#### XSS
4757

automad/lang/english.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,6 @@
432432
"passwordRepeatError": "Please enter twice the same new password!",
433433
"passwordRequirementsError": "A password must at least contain one character of {1} and has a minimum length of {2} characters.",
434434
"passwordResetSave": "Save password",
435-
"passwordResetToken": "Authentication token",
436435
"passwordReuseError": "Don't reuse your old password!",
437436
"penTool": "Pen",
438437
"permissionsDeniedError": "Permissions denied",
@@ -523,7 +522,7 @@
523522
"systemAiCardInfo": "Configure AI providers for an AI assisted editing experience",
524523
"systemAiChangeApiKey": "API key",
525524
"systemAiClaudeSetupHelp": "Using the Claude API requires an account on their <a href='{urlPlatform}' target='_blank'>API platform page</a>, an active billing setup, and a valid API key, which can be managed <a href='{urlApiKeys}' target='_blank'>here</a>.",
526-
"systemAiInfo": "Enable AI-assisted editing to enhance your writing workflow directly in the editor. Use the AI assistant to rewrite, expand, summarize, translate, and refine content, helping you create and improve text more efficiently.",
525+
"systemAiInfo": "AI assistance helps you generate, rewrite, and improve content directly inside content editors. It is an optional feature and you are free to disable it entirely at any time. When turned off, the system will operate without any AI-powered functionality.",
527526
"systemAiOpenAiSetupHelp": "Using OpenAI requires an account on their <a href='{urlPlatform}' target='_blank'>API platform page</a>, an active billing setup, and a valid API key, which can be managed <a href='{urlApiKeys}' target='_blank'>here</a>.",
528527
"systemAiProviderApiKeyModalButton": "Validate and save",
529528
"systemAiProviderApiKeyModalTitle": "API Key",
@@ -565,7 +564,7 @@
565564
"systemMailConfigError": "Error saving mail configuration.",
566565
"systemMailInfo": "You can configure how emails are sent for registration, account recovery or from contact forms on the website. By default, Automad uses PHP's sendmail function for this. However, it is recommended to send emails via an SMTP server, whose access data can be entered below.",
567566
"systemMailReset": "Do you want to reset the current email configuration?",
568-
"systemMailSendTest": "Send test email",
567+
"systemMailSaveSendTest": "Save and send test email",
569568
"systemMailSendTestNoEmail": "There is no email address associated with your user account. Please add a valid email address inside the user settings.",
570569
"systemMailSendTestSuccess": "A test email was successfully sent to",
571570
"systemMailSmtpPasswordPlaceholder": "Leave this field empty in order to keep the existing password",
@@ -699,6 +698,13 @@
699698
"visitSyntaxGallery": "Visit the syntax theme gallery",
700699
"warmthTool": "Warmth",
701700
"watermarkTab": "Watermark",
701+
"wizardButtonBack": "Back",
702+
"wizardButtonFinish": "Finish",
703+
"wizardButtonNext": "Next",
704+
"wizardFinishDialogButton": "Finish configuration",
705+
"wizardFinishDialogText": "You can review and update these settings at any time in the System Settings section. Would you like to finish the configuration wizard now?",
706+
"wizardSubtitle": "You are almost ready. Please review the following settings and confirm that they match your requirements and are configured as intended.",
707+
"wizardTitle": "Complete Your Configuration",
702708
"write": "Write",
703709
"zoomInTitle": "Zoom in",
704710
"zoomOutTitle": "Zoom out"

automad/src/client/admin/components/Forms/SetupForm.ts renamed to automad/src/client/admin/components/Forms/CreateUserForm.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import { FormComponent } from './Form';
4848
*
4949
* @extends FormComponent
5050
*/
51-
export class SetupFormComponent extends FormComponent {
51+
export class CreateUserFormComponent extends FormComponent {
5252
/**
5353
* The callback function used when an element is created in the DOM.
5454
*/
@@ -171,4 +171,4 @@ export class SetupFormComponent extends FormComponent {
171171
}
172172
}
173173

174-
customElements.define('am-setup-form', SetupFormComponent);
174+
customElements.define('am-create-user-form', CreateUserFormComponent);

automad/src/client/admin/components/Forms/MailConfigForm.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,24 +206,35 @@ export class MailConfigFormComponent extends FormComponent {
206206

207207
this.listen(transportSelect, 'change', toggleSmtpCard);
208208

209-
const footer = create('div', [CSS.flex, CSS.flexGap], {}, this);
209+
const footer = create(
210+
'div',
211+
[CSS.flex, CSS.flexGap, CSS.flexWrap],
212+
{},
213+
this
214+
);
210215

211-
create(
212-
'am-submit',
216+
const sendTestMail = create<HTMLButtonElement>(
217+
'button',
213218
[CSS.button, CSS.buttonPrimary],
214-
{ disabled: 'true' },
219+
{},
215220
footer,
216-
App.text('save')
221+
App.text('systemMailSaveSendTest')
217222
);
218223

219224
const reset = create(
220225
'button',
221-
[CSS.button, CSS.buttonDanger],
226+
[CSS.button],
222227
{},
223228
footer,
224229
App.text('reset')
225230
);
226231

232+
this.listen(sendTestMail, 'click', async () => {
233+
await this.submit();
234+
235+
await requestAPI(MailConfigController.test);
236+
});
237+
227238
this.listen(reset, 'click', async () => {
228239
if (!(await confirm(App.text('systemMailReset')))) {
229240
return;

automad/src/client/admin/components/Pages/BaseCenteredLayout.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export abstract class BaseCenteredLayoutComponent extends BaseLayoutComponent {
5252
*/
5353
protected partials: Partials = {
5454
main: this.renderMainPartial(),
55+
variant: this.getVariant(),
5556
};
5657

5758
/**
@@ -60,4 +61,13 @@ export abstract class BaseCenteredLayoutComponent extends BaseLayoutComponent {
6061
* @returns the rendered HTML
6162
*/
6263
protected abstract renderMainPartial(): string;
64+
65+
/**
66+
* Use a custom variant class for the centered content.
67+
*
68+
* @return the variant css class
69+
*/
70+
protected getVariant(): string {
71+
return '';
72+
}
6373
}

automad/src/client/admin/styles/utils/margin.less renamed to automad/src/client/admin/components/Pages/CreateUser.ts

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,54 @@
2222
* :::: :::: ..''
2323
* :::: ..:::: .:''
2424
* '''' '''''
25-
*
25+
*
2626
*
2727
* AUTOMAD
2828
*
29-
* Copyright (c) 2026 by Marc Anton Dahmen
29+
* Copyright (c) 2022-2026 by Marc Anton Dahmen
3030
* https://marcdahmen.de
3131
*
3232
* See LICENSE.md for license information.
3333
*/
3434

35-
.am-u-margin {
36-
&-top-none {
37-
margin-top: 0 !important;
35+
import {
36+
Attr,
37+
getTagFromRoute,
38+
html,
39+
Route,
40+
UserCollectionController,
41+
} from '@/admin/core';
42+
import { BaseCenteredLayoutComponent } from './BaseCenteredLayout';
43+
44+
/**
45+
* The create user view.
46+
*
47+
* @extends BaseCenteredLayoutComponent
48+
*/
49+
export class CreateUserComponent extends BaseCenteredLayoutComponent {
50+
/**
51+
* Set the page title that is used a document title suffix.
52+
*/
53+
protected get pageTitle(): string {
54+
// Setup happens before a user can set a language.
55+
// Therefore the title will be by default in English.
56+
return 'Create User';
57+
}
58+
59+
/**
60+
* Render the main partial.
61+
*
62+
* @returns the rendered HTML
63+
*/
64+
protected renderMainPartial(): string {
65+
return html`
66+
<am-create-user-form
67+
${Attr.api}="${UserCollectionController.createFirstUser}"
68+
${Attr.focus}
69+
${Attr.enter}
70+
></am-create-user-form>
71+
`;
3872
}
3973
}
74+
75+
customElements.define(getTagFromRoute(Route.createuser), CreateUserComponent);

automad/src/client/admin/components/Pages/Partials/System/Mail.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,28 @@
3232
* See LICENSE.md for license information.
3333
*/
3434

35-
import { App, Attr, CSS, EventName, MailConfigController } from '@/admin/core';
35+
import {
36+
App,
37+
Attr,
38+
CSS,
39+
EventName,
40+
html,
41+
MailConfigController,
42+
} from '@/admin/core';
3643

3744
/**
3845
* Render the email section.
3946
*
4047
* @returns the rendered HTML
4148
*/
4249
export const renderMailSection = (): string => {
43-
return `
50+
return html`
4451
<p>${App.text('systemMailInfo')}</p>
4552
<div class="${CSS.flex} ${CSS.flexColumn} ${CSS.flexGapLarge}">
46-
<am-mail-config-form
53+
<am-mail-config-form
4754
${Attr.api}="${MailConfigController.save}"
4855
${Attr.event}="${EventName.appStateRequireUpdate}"
4956
></am-mail-config-form>
50-
<am-form ${Attr.api}=${MailConfigController.test}>
51-
<am-submit class="${CSS.button}">
52-
${App.text('systemMailSendTest')}
53-
</am-submit>
54-
</am-form>
5557
</div>
5658
`;
5759
};

automad/src/client/admin/components/Pages/Partials/System/Users.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ export const renderUsersSection = (): string => {
5757
${Attr.event}="${EventName.appStateRequireUpdate}"
5858
${Attr.watch}
5959
>
60-
<h2 class="${CSS.marginTopNone}">
61-
${App.text('systemUsersYourAccountHeading')}
62-
</h2>
60+
<h2>${App.text('systemUsersYourAccountHeading')}</h2>
6361
<p>${App.text('systemUsersYourAccountText')}</p>
6462
<div class="${CSS.flex} ${CSS.flexColumn} ${CSS.flexGap}">
6563
<am-form-error></am-form-error>

0 commit comments

Comments
 (0)