mirror of
https://github.com/flarum/framework.git
synced 2024-11-30 13:36:10 +08:00
Allow configuring all drivers via frontend (#1169)
This includes an API endpoint for fetching the list of possible drivers and their configuration fields. In the future, this can be extended to include more meta information about each field.
This commit is contained in:
parent
cc92e31174
commit
7ffe1502ee
|
@ -3,36 +3,54 @@ import FieldSet from '../../common/components/FieldSet';
|
|||
import Button from '../../common/components/Button';
|
||||
import Alert from '../../common/components/Alert';
|
||||
import Select from '../../common/components/Select';
|
||||
import LoadingIndicator from '../../common/components/LoadingIndicator';
|
||||
import saveSettings from '../utils/saveSettings';
|
||||
|
||||
export default class MailPage extends Page {
|
||||
init() {
|
||||
super.init();
|
||||
|
||||
this.loading = false;
|
||||
this.loading = true;
|
||||
this.saving = false;
|
||||
|
||||
this.driverFields = {
|
||||
smtp: ['mail_host', 'mail_port', 'mail_encryption', 'mail_username', 'mail_password'],
|
||||
mail: [],
|
||||
log: [],
|
||||
};
|
||||
|
||||
this.fields = [
|
||||
'mail_driver',
|
||||
'mail_host',
|
||||
'mail_from',
|
||||
'mail_port',
|
||||
'mail_username',
|
||||
'mail_password',
|
||||
'mail_encryption'
|
||||
];
|
||||
this.driverFields = {};
|
||||
this.fields = ['mail_driver', 'mail_from'];
|
||||
this.values = {};
|
||||
|
||||
const settings = app.data.settings;
|
||||
this.fields.forEach(key => this.values[key] = m.prop(settings[key]));
|
||||
|
||||
app.request({
|
||||
method: 'GET',
|
||||
url: app.forum.attribute('apiUrl') + '/mail-drivers'
|
||||
}).then(response => {
|
||||
this.driverFields = response['data'].reduce(
|
||||
(hash, driver) => ({...hash, [driver['id']]: driver['attributes']['fields']}),
|
||||
{}
|
||||
);
|
||||
|
||||
Object.keys(this.driverFields).flatMap(key => this.driverFields[key]).forEach(
|
||||
key => {
|
||||
this.fields.push(key);
|
||||
this.values[key] = m.prop(settings[key]);
|
||||
}
|
||||
);
|
||||
this.loading = false;
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
|
||||
view() {
|
||||
if (this.loading) {
|
||||
return (
|
||||
<div className="MailPage">
|
||||
<div className="container">
|
||||
<LoadingIndicator />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="MailPage">
|
||||
<div className="container">
|
||||
|
@ -64,21 +82,15 @@ export default class MailPage extends Page {
|
|||
]
|
||||
})}
|
||||
|
||||
{this.values.mail_driver() == 'smtp' && FieldSet.component({
|
||||
label: app.translator.trans('core.admin.email.smtp_heading'),
|
||||
{Object.keys(this.driverFields[this.values.mail_driver()]).length > 0 && FieldSet.component({
|
||||
label: app.translator.trans(`core.admin.email.${this.values.mail_driver()}_heading`),
|
||||
className: 'MailPage-MailSettings',
|
||||
children: [
|
||||
<div className="MailPage-MailSettings-input">
|
||||
<label>{app.translator.trans('core.admin.email.host_label')}</label>
|
||||
<input className = "FormControl" value={this.values.mail_host() || ''} onInput={m.withAttr('value', this.values.mail_host)} />
|
||||
<label>{app.translator.trans('core.admin.email.port_label')}</label>
|
||||
<input className="FormControl" value={this.values.mail_port() || ''} oninput={m.withAttr('value', this.values.mail_port)} />
|
||||
<label>{app.translator.trans('core.admin.email.encryption_label')}</label>
|
||||
<input className="FormControl" value={this.values.mail_encryption() || ''} oninput={m.withAttr('value', this.values.mail_encryption)} />
|
||||
<label>{app.translator.trans('core.admin.email.username_label')}</label>
|
||||
<input className="FormControl" value={this.values.mail_username() || ''} onInput={m.withAttr('value', this.values.mail_username)}/>
|
||||
<label>{app.translator.trans('core.admin.email.password_label')}</label>
|
||||
<input className="FormControl" value={this.values.mail_password() || ''} onInput={m.withAttr('value', this.values.mail_password)}/>
|
||||
{this.driverFields[this.values.mail_driver()].flatMap(field => [
|
||||
<label>{app.translator.trans(`core.admin.email.${field}_label`)}</label>,
|
||||
<input className="FormControl" value={this.values[field]() || ''} onInput={m.withAttr('value', this.values[field])} />
|
||||
])}
|
||||
</div>
|
||||
]
|
||||
})}
|
||||
|
@ -87,7 +99,7 @@ export default class MailPage extends Page {
|
|||
type: 'submit',
|
||||
className: 'Button Button--primary',
|
||||
children: app.translator.trans('core.admin.email.submit_button'),
|
||||
loading: this.loading,
|
||||
loading: this.saving,
|
||||
disabled: !this.changed()
|
||||
})}
|
||||
</form>
|
||||
|
@ -103,9 +115,9 @@ export default class MailPage extends Page {
|
|||
onsubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.loading) return;
|
||||
if (this.saving) return;
|
||||
|
||||
this.loading = true;
|
||||
this.saving = true;
|
||||
app.alerts.dismiss(this.successAlert);
|
||||
|
||||
const settings = {};
|
||||
|
@ -118,7 +130,7 @@ export default class MailPage extends Page {
|
|||
})
|
||||
.catch(() => {})
|
||||
.then(() => {
|
||||
this.loading = false;
|
||||
this.saving = false;
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Controller;
|
||||
|
||||
use Flarum\Api\Serializer\MailDriverSerializer;
|
||||
use Flarum\User\AssertPermissionTrait;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
||||
class ListMailDriversController extends AbstractListController
|
||||
{
|
||||
use AssertPermissionTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $serializer = MailDriverSerializer::class;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function data(ServerRequestInterface $request, Document $document)
|
||||
{
|
||||
$this->assertAdmin($request->getAttribute('actor'));
|
||||
|
||||
$drivers = self::$container->make('mail.supported_drivers');
|
||||
array_walk($drivers, function (&$driver, $key) {
|
||||
$driver = [
|
||||
'id' => $key,
|
||||
'driver' => self::$container->make($driver),
|
||||
];
|
||||
});
|
||||
|
||||
return $drivers;
|
||||
}
|
||||
}
|
49
framework/core/src/Api/Serializer/MailDriverSerializer.php
Normal file
49
framework/core/src/Api/Serializer/MailDriverSerializer.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Api\Serializer;
|
||||
|
||||
use Flarum\Mail\DriverInterface;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class MailDriverSerializer extends AbstractSerializer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $type = 'mail-drivers';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param \Flarum\Mail\DriverInterface $driver
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function getDefaultAttributes($driver)
|
||||
{
|
||||
if (! ($driver['driver'] instanceof DriverInterface)) {
|
||||
throw new InvalidArgumentException(
|
||||
get_class($this).' can only serialize instances of '.DriverInterface::class
|
||||
);
|
||||
}
|
||||
|
||||
$driver = $driver['driver'];
|
||||
|
||||
return [
|
||||
'fields' => $driver->availableSettings(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getId($model)
|
||||
{
|
||||
return $model['id'];
|
||||
}
|
||||
}
|
|
@ -308,4 +308,11 @@ return function (RouteCollection $map, RouteHandlerFactory $route) {
|
|||
'cache.clear',
|
||||
$route->toController(Controller\ClearCacheController::class)
|
||||
);
|
||||
|
||||
// List available mail drivers and their configuration fields
|
||||
$map->get(
|
||||
'/mail-drivers',
|
||||
'mailDrivers.index',
|
||||
$route->toController(Controller\ListMailDriversController::class)
|
||||
);
|
||||
};
|
||||
|
|
|
@ -24,6 +24,11 @@ use Swift_Transport;
|
|||
*/
|
||||
interface DriverInterface
|
||||
{
|
||||
/**
|
||||
* Provide a list of settings for this driver.
|
||||
*/
|
||||
public function availableSettings(): array;
|
||||
|
||||
/**
|
||||
* Build a mail transport based on Flarum's current settings.
|
||||
*/
|
||||
|
|
|
@ -28,6 +28,11 @@ class LogDriver implements DriverInterface
|
|||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function availableSettings(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
||||
{
|
||||
return new LogTransport($this->logger);
|
||||
|
|
|
@ -18,6 +18,14 @@ use Swift_Transport;
|
|||
|
||||
class MailgunDriver implements DriverInterface
|
||||
{
|
||||
public function availableSettings(): array
|
||||
{
|
||||
return [
|
||||
'mail_mailgun_secret', // the secret key
|
||||
'mail_mailgun_domain', // the API base URL
|
||||
];
|
||||
}
|
||||
|
||||
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
||||
{
|
||||
return new MailgunTransport(
|
||||
|
|
|
@ -18,6 +18,13 @@ use Swift_Transport;
|
|||
|
||||
class MandrillDriver implements DriverInterface
|
||||
{
|
||||
public function availableSettings(): array
|
||||
{
|
||||
return [
|
||||
'mail_mandrill_secret',
|
||||
];
|
||||
}
|
||||
|
||||
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
||||
{
|
||||
return new MandrillTransport(
|
||||
|
|
|
@ -17,6 +17,11 @@ use Swift_Transport;
|
|||
|
||||
class SendmailDriver implements DriverInterface
|
||||
{
|
||||
public function availableSettings(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
||||
{
|
||||
return new Swift_SendmailTransport;
|
||||
|
|
|
@ -18,6 +18,15 @@ use Swift_Transport;
|
|||
|
||||
class SesDriver implements DriverInterface
|
||||
{
|
||||
public function availableSettings(): array
|
||||
{
|
||||
return [
|
||||
'mail_ses_key',
|
||||
'mail_ses_secret',
|
||||
'mail_ses_region',
|
||||
];
|
||||
}
|
||||
|
||||
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
||||
{
|
||||
$config = [
|
||||
|
|
|
@ -17,6 +17,17 @@ use Swift_Transport;
|
|||
|
||||
class SmtpDriver implements DriverInterface
|
||||
{
|
||||
public function availableSettings(): array
|
||||
{
|
||||
return [
|
||||
'mail_host', // a hostname, IPv4 address or IPv6 wrapped in []
|
||||
'mail_port', // a number, defaults to 25
|
||||
'mail_encryption', // "tls" or "ssl"
|
||||
'mail_username', // required
|
||||
'mail_password', // required
|
||||
];
|
||||
}
|
||||
|
||||
public function buildTransport(SettingsRepositoryInterface $settings): Swift_Transport
|
||||
{
|
||||
$transport = new Swift_SmtpTransport(
|
||||
|
|
Loading…
Reference in New Issue
Block a user