Add CSRF protections
This commit is contained in:
@@ -129,6 +129,7 @@ class Action extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$action = $this->action->getById($this->request->getIntegerParam('action_id'));
|
$action = $this->action->getById($this->request->getIntegerParam('action_id'));
|
||||||
|
|
||||||
if ($action && $this->action->remove($action['id'])) {
|
if ($action && $this->action->remove($action['id'])) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace Controller;
|
namespace Controller;
|
||||||
|
|
||||||
use Core\Registry;
|
use Core\Registry;
|
||||||
|
use Core\Security;
|
||||||
use Core\Translator;
|
use Core\Translator;
|
||||||
use Model\LastLogin;
|
use Model\LastLogin;
|
||||||
|
|
||||||
@@ -160,6 +161,28 @@ abstract class Base
|
|||||||
$this->response->html($this->template->layout('app_notfound', array('title' => t('Page not found'))));
|
$this->response->html($this->template->layout('app_notfound', array('title' => t('Page not found'))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application forbidden page
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function forbidden()
|
||||||
|
{
|
||||||
|
$this->response->html($this->template->layout('app_forbidden', array('title' => t('Access Forbidden'))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the CSRF token from the URL is correct
|
||||||
|
*
|
||||||
|
* @access protected
|
||||||
|
*/
|
||||||
|
protected function checkCSRFParam()
|
||||||
|
{
|
||||||
|
if (! Security::validateCSRFToken($this->request->getStringParam('csrf_token'))) {
|
||||||
|
$this->forbidden();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current user have access to the given project
|
* Check if the current user have access to the given project
|
||||||
*
|
*
|
||||||
@@ -171,7 +194,7 @@ abstract class Base
|
|||||||
if ($this->acl->isRegularUser()) {
|
if ($this->acl->isRegularUser()) {
|
||||||
|
|
||||||
if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
|
if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
|
||||||
$this->response->redirect('?controller=project&action=forbidden');
|
$this->forbidden();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace Controller;
|
|||||||
|
|
||||||
use Model\Project as ProjectModel;
|
use Model\Project as ProjectModel;
|
||||||
use Model\User as UserModel;
|
use Model\User as UserModel;
|
||||||
|
use Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Board controller
|
* Board controller
|
||||||
@@ -20,6 +21,7 @@ class Board extends Base
|
|||||||
*/
|
*/
|
||||||
public function moveUp()
|
public function moveUp()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$project_id = $this->request->getIntegerParam('project_id');
|
$project_id = $this->request->getIntegerParam('project_id');
|
||||||
$column_id = $this->request->getIntegerParam('column_id');
|
$column_id = $this->request->getIntegerParam('column_id');
|
||||||
|
|
||||||
@@ -35,6 +37,7 @@ class Board extends Base
|
|||||||
*/
|
*/
|
||||||
public function moveDown()
|
public function moveDown()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$project_id = $this->request->getIntegerParam('project_id');
|
$project_id = $this->request->getIntegerParam('project_id');
|
||||||
$column_id = $this->request->getIntegerParam('column_id');
|
$column_id = $this->request->getIntegerParam('column_id');
|
||||||
|
|
||||||
@@ -344,6 +347,7 @@ class Board extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$column = $this->board->getColumn($this->request->getIntegerParam('column_id'));
|
$column = $this->board->getColumn($this->request->getIntegerParam('column_id'));
|
||||||
|
|
||||||
if ($column && $this->board->removeColumn($column['id'])) {
|
if ($column && $this->board->removeColumn($column['id'])) {
|
||||||
@@ -362,25 +366,31 @@ class Board extends Base
|
|||||||
*/
|
*/
|
||||||
public function save()
|
public function save()
|
||||||
{
|
{
|
||||||
$project_id = $this->request->getIntegerParam('project_id');
|
if ($this->request->isAjax()) {
|
||||||
$values = $this->request->getValues();
|
|
||||||
|
|
||||||
if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
|
$project_id = $this->request->getIntegerParam('project_id');
|
||||||
$this->response->text('Not Authorized', 401);
|
$values = $this->request->getValues();
|
||||||
|
|
||||||
|
if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
|
||||||
|
$this->response->text('Not Authorized', 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($values['positions'])) {
|
||||||
|
$this->board->saveTasksPosition($values['positions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->html(
|
||||||
|
$this->template->load('board_show', array(
|
||||||
|
'current_project_id' => $project_id,
|
||||||
|
'board' => $this->board->get($project_id),
|
||||||
|
'categories' => $this->category->getList($project_id, false),
|
||||||
|
)),
|
||||||
|
201
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (isset($values['positions'])) {
|
$this->response->status(401);
|
||||||
$this->board->saveTasksPosition($values['positions']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->response->html(
|
|
||||||
$this->template->load('board_show', array(
|
|
||||||
'current_project_id' => $project_id,
|
|
||||||
'board' => $this->board->get($project_id),
|
|
||||||
'categories' => $this->category->getList($project_id, false),
|
|
||||||
)),
|
|
||||||
201
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -390,24 +400,30 @@ class Board extends Base
|
|||||||
*/
|
*/
|
||||||
public function check()
|
public function check()
|
||||||
{
|
{
|
||||||
$project_id = $this->request->getIntegerParam('project_id');
|
if ($this->request->isAjax()) {
|
||||||
$timestamp = $this->request->getIntegerParam('timestamp');
|
|
||||||
|
|
||||||
if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
|
$project_id = $this->request->getIntegerParam('project_id');
|
||||||
$this->response->text('Not Authorized', 401);
|
$timestamp = $this->request->getIntegerParam('timestamp');
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->project->isModifiedSince($project_id, $timestamp)) {
|
if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
|
||||||
$this->response->html(
|
$this->response->text('Not Authorized', 401);
|
||||||
$this->template->load('board_show', array(
|
}
|
||||||
'current_project_id' => $project_id,
|
|
||||||
'board' => $this->board->get($project_id),
|
if ($this->project->isModifiedSince($project_id, $timestamp)) {
|
||||||
'categories' => $this->category->getList($project_id, false),
|
$this->response->html(
|
||||||
))
|
$this->template->load('board_show', array(
|
||||||
);
|
'current_project_id' => $project_id,
|
||||||
|
'board' => $this->board->get($project_id),
|
||||||
|
'categories' => $this->category->getList($project_id, false),
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->response->status(304);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$this->response->status(304);
|
$this->response->status(401);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ class Category extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$project = $this->getProject();
|
$project = $this->getProject();
|
||||||
$category = $this->getCategory($project['id']);
|
$category = $this->getCategory($project['id']);
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ class Comment extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$comment = $this->getComment();
|
$comment = $this->getComment();
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ class Config extends Base
|
|||||||
*/
|
*/
|
||||||
public function downloadDb()
|
public function downloadDb()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$this->response->forceDownload('db.sqlite.gz');
|
$this->response->forceDownload('db.sqlite.gz');
|
||||||
$this->response->binary($this->config->downloadDatabase());
|
$this->response->binary($this->config->downloadDatabase());
|
||||||
}
|
}
|
||||||
@@ -87,6 +88,7 @@ class Config extends Base
|
|||||||
*/
|
*/
|
||||||
public function optimizeDb()
|
public function optimizeDb()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$this->config->optimizeDatabase();
|
$this->config->optimizeDatabase();
|
||||||
$this->session->flash(t('Database optimization done.'));
|
$this->session->flash(t('Database optimization done.'));
|
||||||
$this->response->redirect('?controller=config');
|
$this->response->redirect('?controller=config');
|
||||||
@@ -99,6 +101,7 @@ class Config extends Base
|
|||||||
*/
|
*/
|
||||||
public function tokens()
|
public function tokens()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$this->config->regenerateTokens();
|
$this->config->regenerateTokens();
|
||||||
$this->session->flash(t('All tokens have been regenerated.'));
|
$this->session->flash(t('All tokens have been regenerated.'));
|
||||||
$this->response->redirect('?controller=config');
|
$this->response->redirect('?controller=config');
|
||||||
@@ -111,6 +114,7 @@ class Config extends Base
|
|||||||
*/
|
*/
|
||||||
public function removeRememberMeToken()
|
public function removeRememberMeToken()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$this->rememberMe->remove($this->request->getIntegerParam('id'));
|
$this->rememberMe->remove($this->request->getIntegerParam('id'));
|
||||||
$this->response->redirect('?controller=config&action=index#remember-me');
|
$this->response->redirect('?controller=config&action=index#remember-me');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ class File extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
|
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
|
||||||
|
|
||||||
|
|||||||
@@ -12,19 +12,6 @@ use Model\Task as TaskModel;
|
|||||||
*/
|
*/
|
||||||
class Project extends Base
|
class Project extends Base
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Display access forbidden page
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function forbidden()
|
|
||||||
{
|
|
||||||
$this->response->html($this->template->layout('project_forbidden', array(
|
|
||||||
'menu' => 'projects',
|
|
||||||
'title' => t('Access Forbidden')
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task search for a given project
|
* Task search for a given project
|
||||||
*
|
*
|
||||||
@@ -254,6 +241,7 @@ class Project extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$project_id = $this->request->getIntegerParam('project_id');
|
$project_id = $this->request->getIntegerParam('project_id');
|
||||||
|
|
||||||
if ($project_id && $this->project->remove($project_id)) {
|
if ($project_id && $this->project->remove($project_id)) {
|
||||||
@@ -272,6 +260,7 @@ class Project extends Base
|
|||||||
*/
|
*/
|
||||||
public function enable()
|
public function enable()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$project_id = $this->request->getIntegerParam('project_id');
|
$project_id = $this->request->getIntegerParam('project_id');
|
||||||
|
|
||||||
if ($project_id && $this->project->enable($project_id)) {
|
if ($project_id && $this->project->enable($project_id)) {
|
||||||
@@ -290,6 +279,7 @@ class Project extends Base
|
|||||||
*/
|
*/
|
||||||
public function disable()
|
public function disable()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$project_id = $this->request->getIntegerParam('project_id');
|
$project_id = $this->request->getIntegerParam('project_id');
|
||||||
|
|
||||||
if ($project_id && $this->project->disable($project_id)) {
|
if ($project_id && $this->project->disable($project_id)) {
|
||||||
@@ -353,6 +343,8 @@ class Project extends Base
|
|||||||
*/
|
*/
|
||||||
public function revoke()
|
public function revoke()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
|
|
||||||
$values = array(
|
$values = array(
|
||||||
'project_id' => $this->request->getIntegerParam('project_id'),
|
'project_id' => $this->request->getIntegerParam('project_id'),
|
||||||
'user_id' => $this->request->getIntegerParam('user_id'),
|
'user_id' => $this->request->getIntegerParam('user_id'),
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ class Subtask extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$subtask = $this->getSubtask();
|
$subtask = $this->getSubtask();
|
||||||
|
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ class Task extends Base
|
|||||||
*/
|
*/
|
||||||
public function close()
|
public function close()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
if ($this->task->close($task['id'])) {
|
if ($this->task->close($task['id'])) {
|
||||||
@@ -252,6 +253,7 @@ class Task extends Base
|
|||||||
*/
|
*/
|
||||||
public function open()
|
public function open()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
if ($this->task->open($task['id'])) {
|
if ($this->task->open($task['id'])) {
|
||||||
@@ -286,6 +288,7 @@ class Task extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
if ($this->task->remove($task['id'])) {
|
if ($this->task->remove($task['id'])) {
|
||||||
|
|||||||
@@ -10,19 +10,6 @@ namespace Controller;
|
|||||||
*/
|
*/
|
||||||
class User extends Base
|
class User extends Base
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Display access forbidden page
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
*/
|
|
||||||
public function forbidden()
|
|
||||||
{
|
|
||||||
$this->response->html($this->template->layout('user_forbidden', array(
|
|
||||||
'menu' => 'users',
|
|
||||||
'title' => t('Access Forbidden')
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logout and destroy session
|
* Logout and destroy session
|
||||||
*
|
*
|
||||||
@@ -30,6 +17,7 @@ class User extends Base
|
|||||||
*/
|
*/
|
||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$this->rememberMe->destroy($this->acl->getUserId());
|
$this->rememberMe->destroy($this->acl->getUserId());
|
||||||
$this->session->close();
|
$this->session->close();
|
||||||
$this->response->redirect('?controller=user&action=login');
|
$this->response->redirect('?controller=user&action=login');
|
||||||
@@ -42,7 +30,9 @@ class User extends Base
|
|||||||
*/
|
*/
|
||||||
public function login()
|
public function login()
|
||||||
{
|
{
|
||||||
if (isset($_SESSION['user'])) $this->response->redirect('?controller=app');
|
if (isset($_SESSION['user'])) {
|
||||||
|
$this->response->redirect('?controller=app');
|
||||||
|
}
|
||||||
|
|
||||||
$this->response->html($this->template->layout('user_login', array(
|
$this->response->html($this->template->layout('user_login', array(
|
||||||
'errors' => array(),
|
'errors' => array(),
|
||||||
@@ -236,6 +226,7 @@ class User extends Base
|
|||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
$user_id = $this->request->getIntegerParam('user_id');
|
$user_id = $this->request->getIntegerParam('user_id');
|
||||||
|
|
||||||
if ($user_id && $this->user->remove($user_id)) {
|
if ($user_id && $this->user->remove($user_id)) {
|
||||||
@@ -298,6 +289,7 @@ class User extends Base
|
|||||||
*/
|
*/
|
||||||
public function unlinkGoogle()
|
public function unlinkGoogle()
|
||||||
{
|
{
|
||||||
|
$this->checkCSRFParam();
|
||||||
if ($this->google->unlink($this->acl->getUserId())) {
|
if ($this->google->unlink($this->acl->getUserId())) {
|
||||||
$this->session->flash(t('Your Google Account is not linked anymore to your profile.'));
|
$this->session->flash(t('Your Google Account is not linked anymore to your profile.'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace Core;
|
namespace Core;
|
||||||
|
|
||||||
|
use Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request class
|
* Request class
|
||||||
*
|
*
|
||||||
@@ -58,7 +60,12 @@ class Request
|
|||||||
public function getValues()
|
public function getValues()
|
||||||
{
|
{
|
||||||
if (! empty($_POST)) {
|
if (! empty($_POST)) {
|
||||||
return $_POST;
|
|
||||||
|
if (Security::validateCSRFFormToken($_POST)) {
|
||||||
|
return $_POST;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = json_decode($this->getBody(), true);
|
$result = json_decode($this->getBody(), true);
|
||||||
@@ -116,6 +123,19 @@ class Request
|
|||||||
*/
|
*/
|
||||||
public function isAjax()
|
public function isAjax()
|
||||||
{
|
{
|
||||||
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
|
return $this->getHeader('X-Requested-With') === 'XMLHttpRequest';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a HTTP header value
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param string $name Header name
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getHeader($name)
|
||||||
|
{
|
||||||
|
$name = 'HTTP_'.str_replace('-', '_', strtoupper($name));
|
||||||
|
return isset($_SERVER[$name]) ? $_SERVER[$name] : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ class Response
|
|||||||
public function nocache()
|
public function nocache()
|
||||||
{
|
{
|
||||||
header('Pragma: no-cache');
|
header('Pragma: no-cache');
|
||||||
header('Cache-Control: no-cache, must-revalidate');
|
|
||||||
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
|
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
|
||||||
|
|
||||||
|
// Use no-store due to a Chrome bug: https://code.google.com/p/chromium/issues/detail?id=28035
|
||||||
|
header('Cache-Control: no-store, must-revalidate');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
87
app/Core/Security.php
Normal file
87
app/Core/Security.php
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security class
|
||||||
|
*
|
||||||
|
* @package core
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class Security
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generate a random token with different methods: openssl or /dev/urandom or fallback to uniqid()
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return string Random token
|
||||||
|
*/
|
||||||
|
public static function generateToken()
|
||||||
|
{
|
||||||
|
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||||
|
return bin2hex(\openssl_random_pseudo_bytes(30));
|
||||||
|
}
|
||||||
|
else if (ini_get('open_basedir') === '' && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
||||||
|
return hash('sha256', file_get_contents('/dev/urandom', false, null, 0, 30));
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash('sha256', uniqid(mt_rand(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate and store a CSRF token in the current session
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @return string Random token
|
||||||
|
*/
|
||||||
|
public static function getCSRFToken()
|
||||||
|
{
|
||||||
|
$nonce = self::generateToken();
|
||||||
|
|
||||||
|
if (empty($_SESSION['csrf_tokens'])) {
|
||||||
|
$_SESSION['csrf_tokens'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$_SESSION['csrf_tokens'][$nonce] = true;
|
||||||
|
|
||||||
|
return $nonce;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the token exists for the current session (a token can be used only one time)
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param string $token CSRF token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function validateCSRFToken($token)
|
||||||
|
{
|
||||||
|
if (isset($_SESSION['csrf_tokens'][$token])) {
|
||||||
|
unset($_SESSION['csrf_tokens'][$token]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the token used in a form is correct and then remove the value
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @access public
|
||||||
|
* @param array $values Form values
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function validateCSRFFormToken(array &$values)
|
||||||
|
{
|
||||||
|
if (! empty($values['csrf_token']) && self::validateCSRFToken($values['csrf_token'])) {
|
||||||
|
unset($values['csrf_token']);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,23 +55,4 @@ abstract class Base
|
|||||||
$this->db = $db;
|
$this->db = $db;
|
||||||
$this->event = $event;
|
$this->event = $event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a random token with different methods: openssl or /dev/urandom or fallback to uniqid()
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @access public
|
|
||||||
* @return string Random token
|
|
||||||
*/
|
|
||||||
public static function generateToken()
|
|
||||||
{
|
|
||||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
|
||||||
return bin2hex(\openssl_random_pseudo_bytes(16));
|
|
||||||
}
|
|
||||||
else if (ini_get('open_basedir') === '' && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
|
|
||||||
return hash('sha256', file_get_contents('/dev/urandom', false, null, 0, 30));
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash('sha256', uniqid(mt_rand(), true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace Model;
|
|||||||
use SimpleValidator\Validator;
|
use SimpleValidator\Validator;
|
||||||
use SimpleValidator\Validators;
|
use SimpleValidator\Validators;
|
||||||
use Core\Translator;
|
use Core\Translator;
|
||||||
|
use Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config model
|
* Config model
|
||||||
@@ -29,7 +30,7 @@ class Config extends Base
|
|||||||
*/
|
*/
|
||||||
public function getTimezones()
|
public function getTimezones()
|
||||||
{
|
{
|
||||||
$timezones = \timezone_identifiers_list();
|
$timezones = timezone_identifiers_list();
|
||||||
return array_combine(array_values($timezones), $timezones);
|
return array_combine(array_values($timezones), $timezones);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,12 +172,12 @@ class Config extends Base
|
|||||||
*/
|
*/
|
||||||
public function regenerateTokens()
|
public function regenerateTokens()
|
||||||
{
|
{
|
||||||
$this->db->table(self::TABLE)->update(array('webhooks_token' => $this->generateToken()));
|
$this->db->table(self::TABLE)->update(array('webhooks_token' => Security::generateToken()));
|
||||||
|
|
||||||
$projects = $this->db->table(Project::TABLE)->findAllByColumn('id');
|
$projects = $this->db->table(Project::TABLE)->findAllByColumn('id');
|
||||||
|
|
||||||
foreach ($projects as $project_id) {
|
foreach ($projects as $project_id) {
|
||||||
$this->db->table(Project::TABLE)->eq('id', $project_id)->update(array('token' => $this->generateToken()));
|
$this->db->table(Project::TABLE)->eq('id', $project_id)->update(array('token' => Security::generateToken()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace Model;
|
|||||||
use SimpleValidator\Validator;
|
use SimpleValidator\Validator;
|
||||||
use SimpleValidator\Validators;
|
use SimpleValidator\Validators;
|
||||||
use Event\TaskModification;
|
use Event\TaskModification;
|
||||||
|
use Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project model
|
* Project model
|
||||||
@@ -363,7 +364,7 @@ class Project extends Base
|
|||||||
{
|
{
|
||||||
$this->db->startTransaction();
|
$this->db->startTransaction();
|
||||||
|
|
||||||
$values['token'] = self::generateToken();
|
$values['token'] = Security::generateToken();
|
||||||
|
|
||||||
if (! $this->db->table(self::TABLE)->save($values)) {
|
if (! $this->db->table(self::TABLE)->save($values)) {
|
||||||
$this->db->cancelTransaction();
|
$this->db->cancelTransaction();
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace Model;
|
namespace Model;
|
||||||
|
|
||||||
|
use Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RememberMe model
|
* RememberMe model
|
||||||
*
|
*
|
||||||
@@ -174,8 +176,8 @@ class RememberMe extends Base
|
|||||||
*/
|
*/
|
||||||
public function create($user_id, $ip, $user_agent)
|
public function create($user_id, $ip, $user_agent)
|
||||||
{
|
{
|
||||||
$token = hash('sha256', $user_id.$user_agent.$ip.$this->generateToken());
|
$token = hash('sha256', $user_id.$user_agent.$ip.Security::generateToken());
|
||||||
$sequence = $this->generateToken();
|
$sequence = Security::generateToken();
|
||||||
$expiration = time() + self::EXPIRATION;
|
$expiration = time() + self::EXPIRATION;
|
||||||
|
|
||||||
$this->cleanup($user_id);
|
$this->cleanup($user_id);
|
||||||
@@ -225,7 +227,7 @@ class RememberMe extends Base
|
|||||||
*/
|
*/
|
||||||
public function update($token, $sequence)
|
public function update($token, $sequence)
|
||||||
{
|
{
|
||||||
$new_sequence = $this->generateToken();
|
$new_sequence = Security::generateToken();
|
||||||
|
|
||||||
$this->db
|
$this->db
|
||||||
->table(self::TABLE)
|
->table(self::TABLE)
|
||||||
|
|||||||
@@ -263,6 +263,6 @@ function version_1($pdo)
|
|||||||
$pdo->exec("
|
$pdo->exec("
|
||||||
INSERT INTO config
|
INSERT INTO config
|
||||||
(webhooks_token)
|
(webhooks_token)
|
||||||
VALUES ('".\Model\Base::generateToken()."')
|
VALUES ('".\Core\Security::generateToken()."')
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ function version_3($pdo)
|
|||||||
|
|
||||||
foreach ($results as &$result) {
|
foreach ($results as &$result) {
|
||||||
$rq = $pdo->prepare('UPDATE projects SET token=? WHERE id=?');
|
$rq = $pdo->prepare('UPDATE projects SET token=? WHERE id=?');
|
||||||
$rq->execute(array(\Model\Base::generateToken(), $result['id']));
|
$rq->execute(array(\Core\Security::generateToken(), $result['id']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,6 +284,6 @@ function version_1($pdo)
|
|||||||
$pdo->exec("
|
$pdo->exec("
|
||||||
INSERT INTO config
|
INSERT INTO config
|
||||||
(language, webhooks_token)
|
(language, webhooks_token)
|
||||||
VALUES ('en_US', '".\Model\Base::generateToken()."')
|
VALUES ('en_US', '".\Core\Security::generateToken()."')
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
<h3><?= t('Add an action') ?></h3>
|
<h3><?= t('Add an action') ?></h3>
|
||||||
<form method="post" action="?controller=action&action=params&project_id=<?= $project['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=action&action=params&project_id=<?= $project['id'] ?>" autocomplete="off">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('project_id', $values) ?>
|
<?= Helper\form_hidden('project_id', $values) ?>
|
||||||
|
|
||||||
<?= Helper\form_label(t('Event'), 'event_name') ?>
|
<?= Helper\form_label(t('Event'), 'event_name') ?>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<h3><?= t('Define action parameters') ?></h3>
|
<h3><?= t('Define action parameters') ?></h3>
|
||||||
<form method="post" action="?controller=action&action=create&project_id=<?= $project['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=action&action=create&project_id=<?= $project['id'] ?>" autocomplete="off">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('project_id', $values) ?>
|
<?= Helper\form_hidden('project_id', $values) ?>
|
||||||
<?= Helper\form_hidden('event_name', $values) ?>
|
<?= Helper\form_hidden('event_name', $values) ?>
|
||||||
<?= Helper\form_hidden('action_name', $values) ?>
|
<?= Helper\form_hidden('action_name', $values) ?>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=action&action=remove&action_id=<?= $action['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=action&action=remove&action_id=<?= $action['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=action&action=index&project_id=<?= $action['project_id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=action&action=index&project_id=<?= $action['project_id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="alert alert-error">
|
<p class="alert alert-error">
|
||||||
<?= t('Only administrators can access to this page.') ?>
|
<?= t('Access Forbidden') ?>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<section>
|
<section>
|
||||||
<h3><?= t('Change assignee for the task "%s"', $values['title']) ?></h3>
|
<h3><?= t('Change assignee for the task "%s"', $values['title']) ?></h3>
|
||||||
<form method="post" action="?controller=board&action=assignTask" autocomplete="off">
|
<form method="post" action="?controller=board&action=assignTask" autocomplete="off">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('id', $values) ?>
|
<?= Helper\form_hidden('id', $values) ?>
|
||||||
<?= Helper\form_hidden('project_id', $values) ?>
|
<?= Helper\form_hidden('project_id', $values) ?>
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<h3><?= t('Change columns') ?></h3>
|
<h3><?= t('Change columns') ?></h3>
|
||||||
<form method="post" action="?controller=board&action=update&project_id=<?= $project['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=board&action=update&project_id=<?= $project['id'] ?>" autocomplete="off">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?php $i = 0; ?>
|
<?php $i = 0; ?>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -27,12 +27,12 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<?php if ($column['position'] != 1): ?>
|
<?php if ($column['position'] != 1): ?>
|
||||||
<li>
|
<li>
|
||||||
<a href="?controller=board&action=moveUp&project_id=<?= $project['id'] ?>&column_id=<?= $column['id'] ?>"><?= t('Move Up') ?></a>
|
<a href="?controller=board&action=moveUp&project_id=<?= $project['id'] ?>&column_id=<?= $column['id'].Helper\param_csrf() ?>"><?= t('Move Up') ?></a>
|
||||||
</li>
|
</li>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php if ($column['position'] != count($columns)): ?>
|
<?php if ($column['position'] != count($columns)): ?>
|
||||||
<li>
|
<li>
|
||||||
<a href="?controller=board&action=moveDown&project_id=<?= $project['id'] ?>&column_id=<?= $column['id'] ?>"><?= t('Move Down') ?></a>
|
<a href="?controller=board&action=moveDown&project_id=<?= $project['id'] ?>&column_id=<?= $column['id'].Helper\param_csrf() ?>"><?= t('Move Down') ?></a>
|
||||||
</li>
|
</li>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<li>
|
<li>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
<h3><?= t('Add a new column') ?></h3>
|
<h3><?= t('Add a new column') ?></h3>
|
||||||
<form method="post" action="?controller=board&action=add&project_id=<?= $project['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=board&action=add&project_id=<?= $project['id'] ?>" autocomplete="off">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('project_id', $values) ?>
|
<?= Helper\form_hidden('project_id', $values) ?>
|
||||||
<?= Helper\form_label(t('Title'), 'title') ?>
|
<?= Helper\form_label(t('Title'), 'title') ?>
|
||||||
<?= Helper\form_text('title', $values, $errors, array('required')) ?>
|
<?= Helper\form_text('title', $values, $errors, array('required')) ?>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=board&action=remove&column_id=<?= $column['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=board&action=remove&column_id=<?= $column['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=board&action=edit&project_id=<?= $column['project_id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=board&action=edit&project_id=<?= $column['project_id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<table id="board" data-project-id="<?= $current_project_id ?>" data-time="<?= time() ?>" data-check-interval="<?= BOARD_CHECK_INTERVAL ?>">
|
<table id="board" data-project-id="<?= $current_project_id ?>" data-time="<?= time() ?>" data-check-interval="<?= BOARD_CHECK_INTERVAL ?>" data-csrf-token=<?= \Core\Security::getCSRFToken() ?>>
|
||||||
<tr>
|
<tr>
|
||||||
<?php $column_with = round(100 / count($board), 2); ?>
|
<?php $column_with = round(100 / count($board), 2); ?>
|
||||||
<?php foreach ($board as $column): ?>
|
<?php foreach ($board as $column): ?>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<section>
|
<section>
|
||||||
|
|
||||||
<form method="post" action="?controller=category&action=update&project_id=<?= $project['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=category&action=update&project_id=<?= $project['id'] ?>" autocomplete="off">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('id', $values) ?>
|
<?= Helper\form_hidden('id', $values) ?>
|
||||||
<?= Helper\form_hidden('project_id', $values) ?>
|
<?= Helper\form_hidden('project_id', $values) ?>
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
<h3><?= t('Add a new category') ?></h3>
|
<h3><?= t('Add a new category') ?></h3>
|
||||||
<form method="post" action="?controller=category&action=save&project_id=<?= $project['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=category&action=save&project_id=<?= $project['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('project_id', $values) ?>
|
<?= Helper\form_hidden('project_id', $values) ?>
|
||||||
|
|
||||||
<?= Helper\form_label(t('Category Name'), 'name') ?>
|
<?= Helper\form_label(t('Category Name'), 'name') ?>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=category&action=remove&project_id=<?= $project['id'] ?>&category_id=<?= $category['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=category&action=remove&project_id=<?= $project['id'] ?>&category_id=<?= $category['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=category&project_id=<?= $project['id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=category&project_id=<?= $project['id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="post" action="?controller=comment&action=save&task_id=<?= $task['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=comment&action=save&task_id=<?= $task['id'] ?>" autocomplete="off">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('task_id', $values) ?>
|
<?= Helper\form_hidden('task_id', $values) ?>
|
||||||
<?= Helper\form_hidden('user_id', $values) ?>
|
<?= Helper\form_hidden('user_id', $values) ?>
|
||||||
<?= Helper\form_textarea('comment', $values, $errors, array('required', 'placeholder="'.t('Leave a comment').'"'), 'comment-textarea') ?><br/>
|
<?= Helper\form_textarea('comment', $values, $errors, array('required', 'placeholder="'.t('Leave a comment').'"'), 'comment-textarea') ?><br/>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
<form method="post" action="?controller=comment&action=update&task_id=<?= $task['id'] ?>&comment_id=<?= $comment['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=comment&action=update&task_id=<?= $task['id'] ?>&comment_id=<?= $comment['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('id', $values) ?>
|
<?= Helper\form_hidden('id', $values) ?>
|
||||||
<?= Helper\form_textarea('comment', $values, $errors, array('required', 'placeholder="'.t('Leave a comment').'"')) ?><br/>
|
<?= Helper\form_textarea('comment', $values, $errors, array('required', 'placeholder="'.t('Leave a comment').'"')) ?><br/>
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<?= Helper\template('comment_show', array('comment' => $comment, 'task' => $task, 'preview' => true)) ?>
|
<?= Helper\template('comment_show', array('comment' => $comment, 'task' => $task, 'preview' => true)) ?>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=comment&action=remove&task_id=<?= $task['id'] ?>&comment_id=<?= $comment['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=comment&action=remove&task_id=<?= $task['id'] ?>&comment_id=<?= $comment['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>#comment-<?= $comment['id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>#comment-<?= $comment['id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
<section>
|
<section>
|
||||||
<form method="post" action="?controller=config&action=save" autocomplete="off">
|
<form method="post" action="?controller=config&action=save" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<?= Helper\form_label(t('Language'), 'language') ?>
|
<?= Helper\form_label(t('Language'), 'language') ?>
|
||||||
<?= Helper\form_select('language', $languages, $values, $errors) ?><br/>
|
<?= Helper\form_select('language', $languages, $values, $errors) ?><br/>
|
||||||
|
|
||||||
@@ -39,7 +41,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<section class="settings">
|
<section class="settings">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="?controller=config&action=tokens"><?= t('Reset all tokens') ?></a></li>
|
<li><a href="?controller=config&action=tokens<?= Helper\param_csrf() ?>"><?= t('Reset all tokens') ?></a></li>
|
||||||
<li>
|
<li>
|
||||||
<?= t('Webhooks token:') ?>
|
<?= t('Webhooks token:') ?>
|
||||||
<strong><?= Helper\escape($values['webhooks_token']) ?></strong>
|
<strong><?= Helper\escape($values['webhooks_token']) ?></strong>
|
||||||
@@ -50,11 +52,11 @@
|
|||||||
<strong><?= Helper\format_bytes($db_size) ?></strong>
|
<strong><?= Helper\format_bytes($db_size) ?></strong>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="?controller=config&action=downloadDb"><?= t('Download the database') ?></a>
|
<a href="?controller=config&action=downloadDb<?= Helper\param_csrf() ?>"><?= t('Download the database') ?></a>
|
||||||
<?= t('(Gzip compressed Sqlite file)') ?>
|
<?= t('(Gzip compressed Sqlite file)') ?>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="?controller=config&action=optimizeDb"><?= t('Optimize the database') ?></a>
|
<a href="?controller=config&action=optimizeDb <?= Helper\param_csrf() ?>"><?= t('Optimize the database') ?></a>
|
||||||
<?= t('(VACUUM command)') ?>
|
<?= t('(VACUUM command)') ?>
|
||||||
</li>
|
</li>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
@@ -112,7 +114,7 @@
|
|||||||
<td><?= dt('%B %e, %G at %k:%M %p', $session['expiration']) ?></td>
|
<td><?= dt('%B %e, %G at %k:%M %p', $session['expiration']) ?></td>
|
||||||
<td><?= Helper\escape($session['ip']) ?></td>
|
<td><?= Helper\escape($session['ip']) ?></td>
|
||||||
<td><?= Helper\escape($session['user_agent']) ?></td>
|
<td><?= Helper\escape($session['user_agent']) ?></td>
|
||||||
<td><a href="?controller=config&action=removeRememberMeToken&id=<?= $session['id'] ?>"><?= t('Remove') ?></a></td>
|
<td><a href="?controller=config&action=removeRememberMeToken&id=<?= $session['id'].Helper\param_csrf() ?>"><?= t('Remove') ?></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="?controller=file&action=save&task_id=<?= $task['id'] ?>" method="post" enctype="multipart/form-data">
|
<form action="?controller=file&action=save&task_id=<?= $task['id'] ?>" method="post" enctype="multipart/form-data">
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<input type="file" name="files[]" multiple />
|
<input type="file" name="files[]" multiple />
|
||||||
<div class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? Helper\format_bytes($max_size) : $max_size ?></div>
|
<div class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? Helper\format_bytes($max_size) : $max_size ?></div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=file&action=remove&task_id=<?= $task['id'] ?>&file_id=<?= $file['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=file&action=remove&task_id=<?= $task['id'] ?>&file_id=<?= $file['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<a href="?controller=config"><?= t('Settings') ?></a>
|
<a href="?controller=config"><?= t('Settings') ?></a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="?controller=user&action=logout"><?= t('Logout') ?></a>
|
<a href="?controller=user&action=logout<?= Helper\param_csrf() ?>"><?= t('Logout') ?></a>
|
||||||
(<?= Helper\escape(Helper\get_username()) ?>)
|
(<?= Helper\escape(Helper\get_username()) ?>)
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<section>
|
<section>
|
||||||
<form method="post" action="?controller=project&action=update&project_id=<?= $values['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=project&action=update&project_id=<?= $values['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_hidden('id', $values) ?>
|
<?= Helper\form_hidden('id', $values) ?>
|
||||||
|
|
||||||
<?= Helper\form_label(t('Name'), 'name') ?>
|
<?= Helper\form_label(t('Name'), 'name') ?>
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
<section id="main">
|
|
||||||
<div class="page-header">
|
|
||||||
<h2><?= t('Forbidden') ?></h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="alert alert-error">
|
|
||||||
<?= t('You are not allowed to access to this project.') ?>
|
|
||||||
</p>
|
|
||||||
</section>
|
|
||||||
@@ -78,9 +78,9 @@
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<?php if ($project['is_active']): ?>
|
<?php if ($project['is_active']): ?>
|
||||||
<a href="?controller=project&action=disable&project_id=<?= $project['id'] ?>"><?= t('Disable') ?></a>
|
<a href="?controller=project&action=disable&project_id=<?= $project['id'].Helper\param_csrf() ?>"><?= t('Disable') ?></a>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<a href="?controller=project&action=enable&project_id=<?= $project['id'] ?>"><?= t('Enable') ?></a>
|
<a href="?controller=project&action=enable&project_id=<?= $project['id'].Helper\param_csrf() ?>"><?= t('Enable') ?></a>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<section>
|
<section>
|
||||||
<form method="post" action="?controller=project&action=save" autocomplete="off">
|
<form method="post" action="?controller=project&action=save" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
<?= Helper\form_label(t('Name'), 'name') ?>
|
<?= Helper\form_label(t('Name'), 'name') ?>
|
||||||
<?= Helper\form_text('name', $values, $errors, array('autofocus', 'required')) ?>
|
<?= Helper\form_text('name', $values, $errors, array('autofocus', 'required')) ?>
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=project&action=remove&project_id=<?= $project['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=project&action=remove&project_id=<?= $project['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=project"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=project"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
<?php if (! empty($users['not_allowed'])): ?>
|
<?php if (! empty($users['not_allowed'])): ?>
|
||||||
<form method="post" action="?controller=project&action=allow&project_id=<?= $project['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=project&action=allow&project_id=<?= $project['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<?= Helper\form_hidden('project_id', array('project_id' => $project['id'])) ?>
|
<?= Helper\form_hidden('project_id', array('project_id' => $project['id'])) ?>
|
||||||
|
|
||||||
<?= Helper\form_label(t('User'), 'user_id') ?>
|
<?= Helper\form_label(t('User'), 'user_id') ?>
|
||||||
@@ -32,7 +34,7 @@
|
|||||||
<?php foreach ($users['allowed'] as $user_id => $username): ?>
|
<?php foreach ($users['allowed'] as $user_id => $username): ?>
|
||||||
<li>
|
<li>
|
||||||
<strong><?= Helper\escape($username) ?></strong>
|
<strong><?= Helper\escape($username) ?></strong>
|
||||||
(<a href="?controller=project&action=revoke&project_id=<?= $project['id'] ?>&user_id=<?= $user_id ?>"><?= t('revoke') ?></a>)
|
(<a href="?controller=project&action=revoke&project_id=<?= $project['id'] ?>&user_id=<?= $user_id.Helper\param_csrf() ?>"><?= t('revoke') ?></a>)
|
||||||
</li>
|
</li>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
<form method="post" action="?controller=subtask&action=save&task_id=<?= $task['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=subtask&action=save&task_id=<?= $task['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<?= Helper\form_hidden('task_id', $values) ?>
|
<?= Helper\form_hidden('task_id', $values) ?>
|
||||||
|
|
||||||
<?= Helper\form_label(t('Title'), 'title') ?>
|
<?= Helper\form_label(t('Title'), 'title') ?>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
<form method="post" action="?controller=subtask&action=update&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=subtask&action=update&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<?= Helper\form_hidden('id', $values) ?>
|
<?= Helper\form_hidden('id', $values) ?>
|
||||||
<?= Helper\form_hidden('task_id', $values) ?>
|
<?= Helper\form_hidden('task_id', $values) ?>
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<p><strong><?= Helper\escape($subtask['title']) ?></strong></p>
|
<p><strong><?= Helper\escape($subtask['title']) ?></strong></p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=subtask&action=remove&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=subtask&action=remove&task_id=<?= $task['id'] ?>&subtask_id=<?= $subtask['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>#subtasks"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>#subtasks"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=task&action=close&task_id=<?= $task['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=task&action=close&task_id=<?= $task['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -8,6 +8,8 @@
|
|||||||
<section>
|
<section>
|
||||||
<form method="post" action="?controller=task&action=update&task_id=<?= $task['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=task&action=update&task_id=<?= $task['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<div class="form-column">
|
<div class="form-column">
|
||||||
|
|
||||||
<?= Helper\form_label(t('Title'), 'title') ?>
|
<?= Helper\form_label(t('Title'), 'title') ?>
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
<form method="post" action="?controller=task&action=saveDescription&task_id=<?= $task['id'] ?>" autocomplete="off">
|
<form method="post" action="?controller=task&action=saveDescription&task_id=<?= $task['id'] ?>" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<?= Helper\form_hidden('id', $values) ?>
|
<?= Helper\form_hidden('id', $values) ?>
|
||||||
<?= Helper\form_textarea('description', $values, $errors, array('required', 'placeholder="'.t('Leave a description').'"'), 'description-textarea') ?><br/>
|
<?= Helper\form_textarea('description', $values, $errors, array('required', 'placeholder="'.t('Leave a description').'"'), 'description-textarea') ?><br/>
|
||||||
<div class="form-help"><a href="http://kanboard.net/documentation/syntax-guide" target="_blank" rel="noreferrer"><?= t('Write your text in Markdown') ?></a></div>
|
<div class="form-help"><a href="http://kanboard.net/documentation/syntax-guide" target="_blank" rel="noreferrer"><?= t('Write your text in Markdown') ?></a></div>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
<section>
|
<section>
|
||||||
<form method="post" action="?controller=task&action=save" autocomplete="off">
|
<form method="post" action="?controller=task&action=save" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<div class="form-column">
|
<div class="form-column">
|
||||||
<?= Helper\form_label(t('Title'), 'title') ?>
|
<?= Helper\form_label(t('Title'), 'title') ?>
|
||||||
<?= Helper\form_text('title', $values, $errors, array('autofocus', 'required')) ?><br/>
|
<?= Helper\form_text('title', $values, $errors, array('autofocus', 'required')) ?><br/>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=task&action=open&task_id=<?= $task['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=task&action=open&task_id=<?= $task['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=task&action=remove&task_id=<?= $task['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=task&action=remove&task_id=<?= $task['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=task&action=show&task_id=<?= $task['id'] ?>"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -8,6 +8,8 @@
|
|||||||
<section>
|
<section>
|
||||||
<form method="post" action="?controller=user&action=update" autocomplete="off">
|
<form method="post" action="?controller=user&action=update" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<div class="form-column">
|
<div class="form-column">
|
||||||
|
|
||||||
<?= Helper\form_hidden('id', $values) ?>
|
<?= Helper\form_hidden('id', $values) ?>
|
||||||
@@ -48,9 +50,9 @@
|
|||||||
|
|
||||||
<?php if (GOOGLE_AUTH && Helper\is_current_user($values['id'])): ?>
|
<?php if (GOOGLE_AUTH && Helper\is_current_user($values['id'])): ?>
|
||||||
<?php if (empty($values['google_id'])): ?>
|
<?php if (empty($values['google_id'])): ?>
|
||||||
<a href="?controller=user&action=google"><?= t('Link my Google Account') ?></a>
|
<a href="?controller=user&action=google<?= Helper\param_csrf() ?>"><?= t('Link my Google Account') ?></a>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<a href="?controller=user&action=unlinkGoogle"><?= t('Unlink my Google Account') ?></a>
|
<a href="?controller=user&action=unlinkGoogle<?= Helper\param_csrf() ?>"><?= t('Unlink my Google Account') ?></a>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
<form method="post" action="?controller=user&action=check" class="form-login">
|
<form method="post" action="?controller=user&action=check" class="form-login">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<?= Helper\form_label(t('Username'), 'username') ?>
|
<?= Helper\form_label(t('Username'), 'username') ?>
|
||||||
<?= Helper\form_text('username', $values, $errors, array('autofocus', 'required')) ?><br/>
|
<?= Helper\form_text('username', $values, $errors, array('autofocus', 'required')) ?><br/>
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
<section>
|
<section>
|
||||||
<form method="post" action="?controller=user&action=save" autocomplete="off">
|
<form method="post" action="?controller=user&action=save" autocomplete="off">
|
||||||
|
|
||||||
|
<?= Helper\form_csrf() ?>
|
||||||
|
|
||||||
<div class="form-column">
|
<div class="form-column">
|
||||||
|
|
||||||
<?= Helper\form_label(t('Username'), 'username') ?>
|
<?= Helper\form_label(t('Username'), 'username') ?>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<p class="alert alert-info"><?= t('Do you really want to remove this user: "%s"?', $user['username']) ?></p>
|
<p class="alert alert-info"><?= t('Do you really want to remove this user: "%s"?', $user['username']) ?></p>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<a href="?controller=user&action=remove&user_id=<?= $user['id'] ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
<a href="?controller=user&action=remove&user_id=<?= $user['id'].Helper\param_csrf() ?>" class="btn btn-red"><?= t('Yes') ?></a>
|
||||||
<?= t('or') ?> <a href="?controller=user"><?= t('cancel') ?></a>
|
<?= t('or') ?> <a href="?controller=user"><?= t('cancel') ?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
namespace Helper;
|
namespace Helper;
|
||||||
|
|
||||||
|
function param_csrf()
|
||||||
|
{
|
||||||
|
return '&csrf_token='.\Core\Security::getCSRFToken();
|
||||||
|
}
|
||||||
|
|
||||||
function js($filename)
|
function js($filename)
|
||||||
{
|
{
|
||||||
return '<script type="text/javascript" src="'.$filename.'?'.filemtime($filename).'"></script>';
|
return '<script type="text/javascript" src="'.$filename.'?'.filemtime($filename).'"></script>';
|
||||||
@@ -163,6 +168,11 @@ function form_value($values, $name)
|
|||||||
return isset($values[$name]) ? 'value="'.escape($values[$name]).'"' : '';
|
return isset($values[$name]) ? 'value="'.escape($values[$name]).'"' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function form_csrf()
|
||||||
|
{
|
||||||
|
return '<input type="hidden" name="csrf_token" value="'.\Core\Security::getCSRFToken().'"/>';
|
||||||
|
}
|
||||||
|
|
||||||
function form_hidden($name, $values = array())
|
function form_hidden($name, $values = array())
|
||||||
{
|
{
|
||||||
return '<input type="hidden" name="'.$name.'" id="form-'.$name.'" '.form_value($values, $name).'/>';
|
return '<input type="hidden" name="'.$name.'" id="form-'.$name.'" '.form_value($values, $name).'/>';
|
||||||
|
|||||||
@@ -70,8 +70,9 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
url: "?controller=board&action=save&project_id=" + projectId,
|
url: "?controller=board&action=save&project_id=" + projectId,
|
||||||
data: {positions: data},
|
data: {"positions": data, "csrf_token": $("#board").attr("data-csrf-token")},
|
||||||
type: "POST",
|
type: "POST",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$("#board").remove();
|
$("#board").remove();
|
||||||
@@ -90,6 +91,7 @@
|
|||||||
|
|
||||||
if (is_visible() && projectId != undefined && timestamp != undefined) {
|
if (is_visible() && projectId != undefined && timestamp != undefined) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
url: "?controller=board&action=check&project_id=" + projectId + "×tamp=" + timestamp,
|
url: "?controller=board&action=check&project_id=" + projectId + "×tamp=" + timestamp,
|
||||||
statusCode: {
|
statusCode: {
|
||||||
200: function(data) {
|
200: function(data) {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ if (version_compare(PHP_VERSION, '5.5.0', '<')) {
|
|||||||
require __DIR__.'/../vendor/password.php';
|
require __DIR__.'/../vendor/password.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_once __DIR__.'/../app/Core/Security.php';
|
||||||
|
|
||||||
require_once __DIR__.'/../vendor/PicoDb/Database.php';
|
require_once __DIR__.'/../vendor/PicoDb/Database.php';
|
||||||
require_once __DIR__.'/../app/Schema/Sqlite.php';
|
require_once __DIR__.'/../app/Schema/Sqlite.php';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user