Compare commits

..

12 commits
v0.1 ... master

12 changed files with 114 additions and 54 deletions

View file

@ -1,3 +1,15 @@
FrontendSession 0.3 - 2025.01.11
==========================================================
* Require Dotclear 2.33-dev
* Require PHP 8.3
* Add pending user status
FrontendSession 0.2 - 2024.12.31
===========================================================
* Require Dotclear 2.33-dev
* Require PHP 8.3
* Fix widget options
FrontendSession 0.1 - 2024.12.30 FrontendSession 0.1 - 2024.12.30
=========================================================== ===========================================================
* Require Dotclear 2.33-dev * Require Dotclear 2.33-dev

View file

@ -1,51 +1,45 @@
# README # README
[![Release](https://img.shields.io/badge/release-2.3.1-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/cinecturlink2/releases) [![Release](https://img.shields.io/github/v/release/jcdenis/FrontendSession?color=lightblue)](https://git.dotclear.watch/JcDenis/FrontendSession/releases)
![Date](https://img.shields.io/badge/date-2023.11.04-c44d58.svg)] ![Date](https://img.shields.io/github/release-date/jcdenis/FrontendSession?color=red)
[![Dotclear](https://img.shields.io/badge/dotclear-v2.28-137bbb.svg)](https://fr.dotclear.org/download) [![Dotclear](https://img.shields.io/badge/dotclear-v2.33-137bbb.svg)](https://fr.dotclear.org/download)
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/cinecturlink2) [![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/FrontendSession)
[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/cinecturlink2/src/branch/master/LICENSE) [![License](https://img.shields.io/github/license/jcdenis/FrontendSession?color=white)](https://git.dotclear.watch/JcDenis/FrontendSession/src/branch/master/LICENSE)
## ABOUT ## ABOUT
_cinecturlink2_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org). _FrontendSession_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org).
> Widgets and pages about books, musics, films, blogs you are interested in > Allow session on frontend.
It is hightly based on cinecturlink for Dotclear 1 by Tigroux and maintain by brol.
## REQUIREMENTS ## REQUIREMENTS
* Dotclear 2.28 * Dotclear 2.33
* PHP 8.1+ * PHP 8.1+
* Dotclear admin permission for configuration * Dotclear admin permission for configuration
* Dotclear contentadmin permission for management
* System writable directory on public path to store picture
* Note: it also creates dedicated database tables
## USAGE ## USAGE
First install _cinecturlink2_, manualy from a zip package or from First install _FrontendSession_, manualy from a zip package or from
Dotaddict repository. (See Dotclear's documentation to know how do this) Dotaddict repository. (See Dotclear's documentation to know how do this)
Go to ''plugins manager'', expand _cinecturlink2_ information then Once it's done you can manage FrontendSession option from blog preferences.
go to ''configure plugin'', fill in form.
Once it's done you can manage your cinecturlink from menu
''My cinecturlink'' on sidebar or you can add dashboard icon.
There are templates for public page. These template is adapted to There are templates for public page. These template is adapted to
default Dotclear's theme. If you want to create your own template default Dotclear's theme. If you want to create your own template
for your theme, copy files from cinecturlink2/default-templates for your theme, copy files from FrontendSession/default-templates
to your theme tpl path and adapt them. to your theme tpl path and adapt them.
This plugin only manage sign in and session on public pages, nothing more.
Users must exist on Dotclear's database and have rights permissions.
Features enabled by session must be done by others plugins.
## LINKS ## LINKS
* [License](https://git.dotclear.watch/JcDenis/cinecturlink2/src/branch/master/LICENSE) * [License](https://git.dotclear.watch/JcDenis/FrontendSession/src/branch/master/LICENSE)
* [Packages & details](https://git.dotclear.watch/JcDenis/cinecturlink2/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/cinecturlink2)) * [Packages & details](https://git.dotclear.watch/JcDenis/FrontendSession/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/FrontendSession))
* [Sources & contributions](https://git.dotclear.watch/JcDenis/cinecturlink2) (or on [GitHub](https://github.com/JcDenis/cinecturlink2)) * [Sources & contributions](https://git.dotclear.watch/JcDenis/FrontendSession) (or on [GitHub](https://github.com/JcDenis/FrontendSession))
* [Issues & security](https://git.dotclear.watch/JcDenis/cinecturlink2/issues) (or on [GitHub](https://github.com/JcDenis/cinecturlink2/issues)) * [Issues & security](https://git.dotclear.watch/JcDenis/FrontendSession/issues) (or on [GitHub](https://github.com/JcDenis/FrontendSession/issues))
* [Discuss and help](https://forum.dotclear.org/viewtopic.php?id=40893)
## CONTRIBUTORS ## CONTRIBUTORS

View file

@ -17,14 +17,14 @@ $this->registerModule(
'Frontend sessions', 'Frontend sessions',
'Allow session on frontend.', 'Allow session on frontend.',
'Jean-Christian Paul Denis and Contributors', 'Jean-Christian Paul Denis and Contributors',
'0.1', '0.3',
[ [
'requires' => [['core', '2.33']], 'requires' => [['core', '2.33']],
'settings' => ['blog' => '#params.' . basename(__DIR__) . '_params'], 'settings' => ['blog' => '#params.' . $this->id . '_params'],
'permissions' => 'My', 'permissions' => 'My',
'type' => 'plugin', 'type' => 'plugin',
'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues', 'support' => 'https://git.dotclear.watch/JcDenis/' . $this->id . '/issues',
'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md', 'details' => 'https://git.dotclear.watch/JcDenis/' . $this->id . '/src/branch/master/README.md',
'repository' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/raw/branch/master/dcstore.xml', 'repository' => 'https://git.dotclear.watch/JcDenis/' . $this->id . '/raw/branch/master/dcstore.xml',
] ]
); );

View file

@ -2,10 +2,10 @@
<modules xmlns:da="http://dotaddict.org/da/"> <modules xmlns:da="http://dotaddict.org/da/">
<module id="FrontendSession"> <module id="FrontendSession">
<name>Frontend Session</name> <name>Frontend Session</name>
<version>0.1</version> <version>0.3</version>
<author>Jean-Christian Paul Denis and contributors</author> <author>Jean-Christian Paul Denis and contributors</author>
<desc>Allow session on frontend.</desc> <desc>Allow session on frontend.</desc>
<file>https://github.com/JcDenis/FrontendSession/releases/download/v0.1/plugin-FrontendSession.zip</file> <file>https://github.com/JcDenis/FrontendSession/releases/download/v0.3/plugin-FrontendSession.zip</file>
<da:dcmin>2.33</da:dcmin> <da:dcmin>2.33</da:dcmin>
<da:details>https://git.dotclear.watch/JcDenis/FrontendSession/src/branch/master/README.md</da:details> <da:details>https://git.dotclear.watch/JcDenis/FrontendSession/src/branch/master/README.md</da:details>
<da:support>https://git.dotclear.watch/JcDenis/FrontendSession/issues</da:support> <da:support>https://git.dotclear.watch/JcDenis/FrontendSession/issues</da:support>

View file

@ -47,7 +47,7 @@
<input type="password" id="{{tpl:FrontendSessionID}}_page_password" name="{{tpl:FrontendSessionID}}_password" value="" /> <input type="password" id="{{tpl:FrontendSessionID}}_page_password" name="{{tpl:FrontendSessionID}}_password" value="" />
</p> </p>
<p> <p>
<input class="submit" type="submit" id="{{tpl:FrontendSessionID}}_page_submit" name="{{tpl:FrontendSessionID}}_submit" value="{{tpl:lang Start to share}}" /> <input class="submit" type="submit" id="{{tpl:FrontendSessionID}}_page_submit" name="{{tpl:FrontendSessionID}}_submit" value="{{tpl:lang Connect}}" />
</p> </p>
</form> </form>
</div> </div>

5
icon.svg Normal file
View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="64px" height="64px" viewBox="0 0 24 24" id="_24x24_On_Light_Session-Join" data-name="24x24/On Light/Session-Join" xmlns="http://www.w3.org/2000/svg">
<rect id="view-box" width="24" height="24" fill="none"/>
<path id="Shape" d="M5.75,17.5a.75.75,0,0,1,0-1.5h8.8A1.363,1.363,0,0,0,16,14.75v-12A1.363,1.363,0,0,0,14.55,1.5H5.75a.75.75,0,0,1,0-1.5h8.8A2.853,2.853,0,0,1,17.5,2.75v12A2.853,2.853,0,0,1,14.55,17.5ZM7.22,13.28a.75.75,0,0,1,0-1.061L9.939,9.5H.75A.75.75,0,0,1,.75,8H9.94L7.22,5.28A.75.75,0,0,1,8.28,4.22l4,4,.013.013.005.006.007.008.007.008,0,.005.008.009,0,0,.008.01,0,0,.008.011,0,0,.008.011,0,0,.008.011,0,0,.007.011,0,.005.006.01,0,.007,0,.008,0,.009,0,.006.006.011,0,0,.008.015h0a.751.751,0,0,1-.157.878L8.28,13.28a.75.75,0,0,1-1.06,0Z" transform="translate(3.25 3.25)" fill="#b2b2b2"/>
</svg>

After

Width:  |  Height:  |  Size: 865 B

View file

@ -7,6 +7,7 @@ namespace Dotclear\Plugin\FrontendSession;
use ArrayObject; use ArrayObject;
use Dotclear\App; use Dotclear\App;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Core\Backend\Notices;
use Dotclear\Helper\Html\Form\{ use Dotclear\Helper\Html\Form\{
Checkbox, Checkbox,
Div, Div,
@ -16,6 +17,7 @@ use Dotclear\Helper\Html\Form\{
Textarea Textarea
}; };
use Dotclear\Helper\Html\Html; use Dotclear\Helper\Html\Html;
use Dotclear\Helper\Network\Http;
use Dotclear\Interface\Core\BlogSettingsInterface; use Dotclear\Interface\Core\BlogSettingsInterface;
/** /**
@ -93,6 +95,23 @@ class Backend extends Process
$attr[2] = App::blog()->url() . App::url()->getURLFor(My::id()); $attr[2] = App::blog()->url() . App::url()->getURLFor(My::id());
} }
}, },
'adminUsersActions' => function (array $users, array $blogs, string $action, string $redir): void {
if ($action == My::id()) {
foreach ($users as $u) {
try {
$cur = App::auth()->openUserCursor();
$cur->user_status = My::USER_PENDING;
App::users()->updUser($u, $cur);
} catch (Exception $e) {
App::error()->add($e->getMessage());
}
}
if (!App::error()->flag()) {
Notices::addSuccessNotice(__('User has been successfully marked as pending.'));
Http::redirect($redir);
}
}
},
]); ]);
return true; return true;

View file

@ -93,7 +93,17 @@ class Frontend extends Process
// we check the user and its perm // we check the user and its perm
if (App::auth()->checkUser($user_id, $user_pwd, $user_key, false) === true if (App::auth()->checkUser($user_id, $user_pwd, $user_key, false) === true
&& App::auth()->check(My::id(), App::blog()->id()) === true && App::auth()->check(My::id(), App::blog()->id()) === true
//&& !App::status()->user()->isRestricted((int) App::auth()->getInfo('user_status'))
) { ) {
// check if user is pending activation
if ((int) App::auth()->getInfo('user_status') == My::USER_PENDING) {
self::resetCookie();
Http::redirect(App::blog()->url() . App::url()->getURLFor(My::id()) . '/pending');
// check if user is not enabled
} elseif (App::status()->user()->isRestricted((int) App::auth()->getInfo('user_status'))) {
self::resetCookie();
Http::redirect(Http::getSelfURI());
} else {
if ($user_key === null) { if ($user_key === null) {
$cookie_console = Http::browserUID( $cookie_console = Http::browserUID(
App::config()->masterKey() . App::config()->masterKey() .
@ -104,19 +114,26 @@ class Frontend extends Process
$cookie_console = $_COOKIE[My::id()]; $cookie_console = $_COOKIE[My::id()];
} }
setcookie(My::id(), $cookie_console, strtotime('+20 hours'), '/', '', self::useSSL()); setcookie(My::id(), $cookie_console, strtotime('+20 hours'), '/', '', self::useSSL());
} else {
//App::frontend()->context()->form_error = __("Error: your password may be wrong or you haven't an account or you haven't ask for its activation.");
if (isset($_COOKIE[My::id()])) {
unset($_COOKIE[My::id()]);
setcookie(My::id(), '', time() - 3600, '/', '', self::useSSL());
} }
} else {
self::resetCookie();
// need to replay doAuthControl() to remove user information from Auth if it exists but have no permissions // need to replay doAuthControl() to remove user information from Auth if it exists but have no permissions
Http::redirect(Http::getSelfURI()); Http::redirect(Http::getSelfURI());
} }
} }
} }
/**
* Remove cookie
*/
public static function resetCookie(): void
{
if (isset($_COOKIE[My::id()])) {
unset($_COOKIE[My::id()]);
setcookie(My::id(), '', time() - 3600, '/', '', self::useSSL());
}
}
/** /**
* Check SSL. * Check SSL.
*/ */

View file

@ -18,5 +18,5 @@ use Dotclear\Module\MyPlugin;
*/ */
class My extends MyPlugin class My extends MyPlugin
{ {
// nothing special public const USER_PENDING = -201;
} }

View file

@ -5,9 +5,8 @@ declare(strict_types=1);
namespace Dotclear\Plugin\FrontendSession; namespace Dotclear\Plugin\FrontendSession;
use Dotclear\App; use Dotclear\App;
use Dotclear\Core\PostType;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Database\MetaRecord; use Dotclear\Helper\Stack\Status;
/** /**
* @brief FrontendSession module prepend. * @brief FrontendSession module prepend.
@ -29,13 +28,13 @@ class Prepend extends Process
return false; return false;
} }
// contributor permission // Add frontend permission (required to login in frontend)
App::auth()->setPermissionType( App::auth()->setPermissionType(
My::id(), My::id(),
My::name() . ':' . __('Frontend') My::name()
); );
// add session login URL // Add session login URL
App::url()->register( App::url()->register(
My::id(), My::id(),
'session/login', 'session/login',
@ -43,6 +42,15 @@ class Prepend extends Process
[UrlHandler::class, 'sessionLogin'] [UrlHandler::class, 'sessionLogin']
); );
// Add user status
App::status()->user()->set((new Status(
My::USER_PENDING ,
My::id(),
'Pending registration',
'pending registration (>1)',
My::fileURL('icon.svg'))
));
return true; return true;
} }
} }

View file

@ -49,6 +49,10 @@ class UrlHandler extends Url
App::blog()->triggerBlog(); App::blog()->triggerBlog();
Http::redirect(App::blog()->url()); Http::redirect(App::blog()->url());
// user pending activation
} elseif (is_array($args) && $args[0] == 'pending' && App::auth()->userID() == '') {
App::frontend()->context()->form_error = __("Error: your account is not yet activated.");
self::serveTemplate(My::id() . '.html');
// no loggin session, go to login page // no loggin session, go to login page
} elseif (App::auth()->userID() == '') { } elseif (App::auth()->userID() == '') {
self::serveTemplate(My::id() . '.html'); self::serveTemplate(My::id() . '.html');

View file

@ -35,6 +35,7 @@ class Widgets
'Public login form' 'Public login form'
) )
->addTitle(__('Login')) ->addTitle(__('Login'))
->addHomeOnly()
->addContentOnly() ->addContentOnly()
->addClass() ->addClass()
->addOffline(); ->addOffline();
@ -58,7 +59,7 @@ class Widgets
} else { } else {
$res .= '<form method="post" name="' . My::id() . '_form" id="' . My::id() . '_widget_form" action="">'; $res .= '<form method="post" name="' . My::id() . '_form" id="' . My::id() . '_widget_form" action="">';
if (App::frontend()->context()->form_error !== null) { if (App::frontend()->context()->form_error !== null) {
$res .= '<p class="erreur">' . Html::escapeHTML(App::frontend()->context()->form_error) . '</p>'; //$res .= '<p class="erreur">' . Html::escapeHTML(App::frontend()->context()->form_error) . '</p>';
} }
$res .= '<p>' . $res .= '<p>' .
'<label for="' . My::id() . '_login" class="required">' . __('Login:') . '</label><br />' . '<label for="' . My::id() . '_login" class="required">' . __('Login:') . '</label><br />' .