Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions administrator/components/com_config/forms/application.xml
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@
<option value="mail">COM_CONFIG_FIELD_VALUE_PHP_MAIL</option>
<option value="sendmail">COM_CONFIG_FIELD_VALUE_SENDMAIL</option>
<option value="smtp">COM_CONFIG_FIELD_VALUE_SMTP</option>
<option value="smtpoauth">COM_CONFIG_FIELD_VALUE_SMTPOAUTH</option>
</field>

<field
Expand Down Expand Up @@ -616,6 +617,14 @@
lock="true"
/>

<field
name="smtpoauthx"
type="OAuth2Client"
label="COM_CONFIG_FIELD_MAIL_SMTP_OAUTH2CLIENT_LABEL"
showon="mailonline:1[AND]mailer:smtpoauth"
callback_url="/administrator/index.php?option=com_config%26task=callback.mailer"
/>

</fieldset>

<fieldset
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

/**
* @package Joomla.Administrator
* @subpackage com_config
*
* @copyright (C) 2025 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/

namespace Joomla\Component\Config\Administrator\Controller;

use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Event\MultiFactor\Callback;
use Joomla\CMS\Language\Text;
use Joomla\CMS\MVC\Controller\BaseController;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Input\Input;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
* OAuth2 AJAX callback controller for mailer
*
* @since __DEPLOY_VERSION__
*/
class CallbackController extends BaseController
{
/**
* Public constructor
*
* @param array $config Plugin configuration
* @param ?MVCFactoryInterface $factory MVC Factory for the com_users component
* @param ?CMSApplication $app CMS application object
* @param ?Input $input Joomla CMS input object
*
* @since __DEPLOY_VERSION__
*/
public function __construct(array $config = [], ?MVCFactoryInterface $factory = null, ?CMSApplication $app = null, ?Input $input = null)
{
parent::__construct($config, $factory, $app, $input);

$this->registerDefaultTask('mailer');
}

/**
* Handles an OAuth Callback request for OAuth2
*
* @param bool $cachable Can this view be cached
* @param array|bool $urlparams An array of safe url parameters and their variable types.
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
*
* @return void
* @since __DEPLOY_VERSION__
*/
protected function callback($cachable = false, $urlparams = false): void
{
/**
* If we are still here and no method handled the request successfully. Show an error.
*/
throw new \RuntimeException(Text::_('JERROR_ALERTNOAUTHOR'), 403);
}

/**
* Handles an OAuth Callback request for phpmailer
*
* URLs containing [sitename]/administrator/index.php?option=com_config&task=callback.mailer
*
* @param bool $cachable Can this view be cached
* @param array|bool $urlparams An array of safe url parameters and their variable types.
* @see \Joomla\CMS\Filter\InputFilter::clean() for valid values.
*
* @return void
* @since __DEPLOY_VERSION__
*/
public function mailer($cachable = false, $urlparams = false): void
{
// Redirect
$this->redirect();
}
}
2 changes: 2 additions & 0 deletions administrator/language/en-GB/com_config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ COM_CONFIG_FIELD_LOG_PRIORITIES_WARNING="Warning"
COM_CONFIG_FIELD_MAIL_FROM_EMAIL_LABEL="From Email"
COM_CONFIG_FIELD_MAIL_FROM_NAME_LABEL="From Name"
COM_CONFIG_FIELD_MAIL_MAILER_LABEL="Mailer"
COM_CONFIG_FIELD_MAIL_SMTP_OAUTH2CLIENT_LABEL="SMTP XOAuth"
COM_CONFIG_FIELD_MAIL_MAILONLINE_LABEL="Send Mail"
COM_CONFIG_FIELD_MAIL_MASSMAILOFF_DESC="Joomla offers a Mass Mail feature which allows a user with administrator access to send an email to all users of the site. On sites with more than a few dozen users this can be problematic or time out."
COM_CONFIG_FIELD_MAIL_MASSMAILOFF_LABEL="Disable Mass Mail"
Expand Down Expand Up @@ -204,6 +205,7 @@ COM_CONFIG_FIELD_VALUE_SENDMAIL="Sendmail"
COM_CONFIG_FIELD_VALUE_SIMPLE="Simple"
COM_CONFIG_FIELD_VALUE_SITE_EMAIL="Site Email"
COM_CONFIG_FIELD_VALUE_SMTP="SMTP"
COM_CONFIG_FIELD_VALUE_SMTPOAUTH="SMTP OAuth2"
COM_CONFIG_FIELD_VALUE_SSL="SSL/TLS"
COM_CONFIG_FIELD_VALUE_SYSTEM_DEFAULT="System Default"
COM_CONFIG_FIELD_VALUE_TLS="STARTTLS"
Expand Down
8 changes: 8 additions & 0 deletions administrator/language/en-GB/lib_joomla.ini
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,14 @@ JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_DESC="Shows or hides the preview of the sele
JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_INLINE="Inline"
JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_LABEL="Preview"
JLIB_FORM_FIELD_PARAM_MEDIA_PREVIEW_TOOLTIP="Tooltip"
JLIB_FORM_FIELD_PARAM_OAUTH2CLIENT_LABEL="OAuth2 Client"
JLIB_FORM_FIELD_PARAM_OAUTH_PROVIDER_LABEL="Provider" ; @todo ???
JLIB_FORM_FIELD_PARAM_OAUTH_TOKEN_URL_LABEL="Token URL"
JLIB_FORM_FIELD_PARAM_OAUTH_AUTH_URL_LABEL="Authorization URL"
JLIB_FORM_FIELD_PARAM_OAUTH_URL_LABEL="OAuth URL"
JLIB_FORM_FIELD_PARAM_OAUTH_CLIENT_ID_LABEL="Client ID"
JLIB_FORM_FIELD_PARAM_OAUTH_CLIENT_SECRET_LABEL="Client Secret"
JLIB_FORM_FIELD_PARAM_OAUTH_CALLBACK_LABEL="Callback URL"
JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_DESC="Allow multiple values to be selected."
JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_LABEL="Multiple"
JLIB_FORM_FIELD_PARAM_RADIO_MULTIPLE_VALUES_DESC="The options of the list."
Expand Down
216 changes: 216 additions & 0 deletions libraries/src/Form/Field/OAuth2ClientField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?php

/**
* Joomla! Content Management System
*
* @copyright (C) 2025 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/

namespace Joomla\CMS\Form\Field;

use Joomla\OAuth2\Client;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
* The Field to load the form for OAuth2 client configuration inside current form
*
* @since __DEPLOY_VERSION__
*/
class OAuth2ClientField extends SubformField
{
/**
* The form field type.
*
* @var string
* @since __DEPLOY_VERSION__
*/
protected $type = 'OAuth2Client';

/**
* The callback url
*
* @var string
* @since __DEPLOY_VERSION__
*/
protected $callbackUrl;

/**
* Layout to render
*
* @var string
* @since __DEPLOY_VERSION__
*/
protected $layout;

/**
* Method to get certain otherwise inaccessible properties from the form field object.
*
* @param string $name The property name for which to get the value.
*
* @return mixed The property value or null.
*
* @since __DEPLOY_VERSION__
*/
public function __get($name)
{
switch ($name) {
case 'callbackUrl':
return $this->$name;
}

return parent::__get($name);
}

/**
* Method to set certain otherwise inaccessible properties of the form field object.
*
* @param string $name The property name for which to set the value.
* @param mixed $value The value of the property.
*
* @return void
*
* @since __DEPLOY_VERSION__
*/
public function __set($name, $value)
{
switch ($name) {
case 'callbackUrl':
$this->$name = (string) $value;
break;

default:
parent::__set($name, $value);
}
}

/**
* Method to attach a Form object to the field.
*
* @param \SimpleXMLElement $element The SimpleXMLElement object representing the <field /> tag for the form field object.
* @param mixed $value The form field value to validate.
* @param string $group The field name group control value.
*
* @return boolean True on success.
*
* @since __DEPLOY_VERSION__
*/
public function setup(\SimpleXMLElement $element, $value, $group = null)
{
/**
* When you have subforms which are not repeatable (i.e. a subform custom field with the
* repeat attribute set to 0) you get an array here since the data comes from decoding the
* JSON into an associative array, including the media subfield's data.
*
* However, this method expects an object or a string, not an array. Typecasting the array
* to an object solves the data format discrepancy.
*/
$value = \is_array($value) ? (object) $value : $value;

/**
* If the value is not a string, it is
* most likely within a custom field of type subform
* and the value is a stdClass with properties
* imagefile and alt_text. So it is fine.
*/
// @todo
if (\is_string($value)) {
json_decode($value);

// Check if value is a valid JSON string.
if ($value !== '' && json_last_error() !== JSON_ERROR_NONE) {
/**
* If the value is not empty and is not a valid JSON string,
* it is most likely a custom field created in Joomla 3 and
* the value is a string that contains the file name.
*/
if (is_file(JPATH_ROOT . '/' . $value)) {
$value = '{"imagefile":"' . $value . '","alt_text":""}';
} else {
$value = '';
}
}
} elseif (
!\is_object($value)
|| !property_exists($value, 'imagefile')
|| !property_exists($value, 'alt_text')
) {
return false;
}

if (!parent::setup($element, $value, $group)) {
return false;
}

$this->callbackUrl = (string) $this->element['callback_url'];

$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<form
name="oauth2client"
label="JLIB_FORM_FIELD_PARAM_OAUTH2CLIENT_LABEL"
>
<fieldset
name="oauth2clientconfig"
label="JLIB_FORM_FIELD_PARAM_OAUTH2CLIENT_LABEL"
>
<field
name="oauth_provider"
type="list"
label="JLIB_FORM_FIELD_PARAM_OAUTH_PROVIDER_LABEL"
default="Google"
filter="string"
validate="options"
>
<option value="Google">Google</option>
</field>

<field
name="oauth_tokenurl"
type="text"
label="JLIB_FORM_FIELD_PARAM_OAUTH_TOKEN_URL_LABEL"
filter="string"
/>

<field
name="oauth_authurl"
type="text"
label="JLIB_FORM_FIELD_PARAM_OAUTH_AUTH_URL_LABEL"
filter="string"
/>

<field
name="oauth_client_id"
type="text"
label="JLIB_FORM_FIELD_PARAM_OAUTH_CLIENT_ID_LABEL"
filter="string"
/>

<field
name="oauth_client_secret"
type="password"
label="JLIB_FORM_FIELD_PARAM_OAUTH_CLIENT_SECRET_LABEL"
filter="raw"
lock="true"
/>

<field
name="noteCallbackUrl"
type="note"
description="JLIB_FORM_FIELD_PARAM_OAUTH_CALLBACK_LABEL"
class="alert alert-info w-100 mt-2"
/>

</fieldset>
</form>
XML;
$this->formsource = $xml;

$this->layout = 'joomla.form.field.subform.default';

return true;
}
}
Loading