Skip to content

Commit

Permalink
Merge branch 'master' into newSessionHandling
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelfolaron committed Jun 10, 2024
2 parents f562ad3 + ddaae67 commit e74d98d
Show file tree
Hide file tree
Showing 49 changed files with 214 additions and 265 deletions.
247 changes: 30 additions & 217 deletions CHANGELOG.md

Large diffs are not rendered by default.

43 changes: 37 additions & 6 deletions app/Core/Middleware/RequestRateLimiter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

use Closure;
use Illuminate\Cache\RateLimiter;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Support\Facades\Cache;
use Leantime\Core\ApiRequest;
use Leantime\Core\Environment;
use Leantime\Core\Eventhelpers;
use Leantime\Core\Frontcontroller;
use Leantime\Core\IncomingRequest;
Expand Down Expand Up @@ -41,11 +43,16 @@ public function __construct()
* Handle the incoming request.
*
* @param IncomingRequest $request The incoming request object.
* @param Closure $next The next middleware closure.
* @param Closure $next The next middleware closure.
* @return Response The response object.
* @throws BindingResolutionException
*/
public function handle(IncomingRequest $request, Closure $next): Response
{
//Configurable rate limits
$rateLimitGeneral = app()->make(Environment::class)->get('LEAN_RATELIMIT_GENERAL') ?? 1000;
$rateLimitApi = app()->make(Environment::class)->get('LEAN_RATELIMIT_API') ?? 10;
$rateLimitAuth = app()->make(Environment::class)->get('LEAN_RATELIMIT_AUTH') ?? 20;

//Key
$keyModifier = "-1";
Expand All @@ -56,19 +63,19 @@ public function handle(IncomingRequest $request, Closure $next): Response
$key = $request->getClientIp()."-".$keyModifier;

//General Limit per minute
$limit = 2000;
$limit = $rateLimitGeneral;

//API Routes Limit
if ($request instanceof ApiRequest) {
$apiKey = "";
$key = app()->make(Api::class)->getAPIKeyUser($apiKey);
$limit = 10;
$limit = $rateLimitApi;
}

$route = Frontcontroller::getCurrentRoute();

if ($route == "auth.login") {
$limit = 50;
$limit = $rateLimitAuth;
$key = $key . ".loginAttempts";
}

Expand All @@ -88,13 +95,37 @@ public function handle(IncomingRequest $request, Closure $next): Response
"key" => $key,
],
);

if ($this->limiter->tooManyAttempts($key, $limit)) {
error_log("too many requests per minute: " . $key);
return new Response(json_encode(['error' => 'Too many requests per minute.']), Response::HTTP_TOO_MANY_REQUESTS);
return new Response(
json_encode(['error' => 'Too many requests per minute.']),
Response::HTTP_TOO_MANY_REQUESTS,
$this->getHeaders($key, $limit),
);
}

$this->limiter->hit($key, 60);

return $next($request);
}


/**
* Get rate limiter headers for response.
*
* @param string $key
*
* @param string $limit
*
* @return array
*/
private function getHeaders(string $key, string $limit): array
{
return [
'X-RateLimit-Remaining' => $this->limiter->retriesLeft($key, $limit),
'X-RateLimit-Retry-After' => $this->limiter->availableIn($key),
'X-RateLimit-Limit' => $this->limiter->attempts($key),
'Retry-After' => $this->limiter->availableIn($key),
];
}
}
68 changes: 33 additions & 35 deletions app/Domain/Notifications/Services/Messengers.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,23 +203,28 @@ private function zulipWebhook(NotificationModel $notification): bool
*/
public function discordWebhook(NotificationModel $notification): bool
{
$converter = false;
$ticketService = app()->make(Tickets::class);

for ($i = 1; 3 >= $i; $i++) {
$discordWebhookURL = $this->settingsRepo->getSetting("projectsettings.{$notification->projectId}.discordWebhookURL{$i}");
if ($discordWebhookURL !== '' && $discordWebhookURL !== false) {
if (!$converter) {
$converter = new HtmlConverter();
}
$timestamp = date('c', strtotime('now'));
$fields = [
// Additional data to be sent; e.g.:
//[
// 'name' => $subject,
// 'value' => $message,
// 'inline' => FALSE
//],
[
'name' => $this->language->__("label.project"),
'value' => $this->projectName,
'inline' => true
],
];

$statusLabelsArray = $ticketService->getStatusLabels($notification->projectId);
if (!empty($notification->entity->status) && !empty($statusLabelsArray[$notification->entity->status])) {
$fields[] = [
'name' => $this->language->__("label.todo_status"),
'value' => $statusLabelsArray[$notification->entity->status]['name'],
'inline' => true
];
}

$url_link = (
empty($notification->url['url'])
? ''
Expand All @@ -232,24 +237,13 @@ public function discordWebhook(NotificationModel $notification): bool
'tts' => false,
'embeds' => [
[
'title' => $notification->subject,
'type' => 'rich',
'description' => html_entity_decode($converter->convert($notification->message)),
'url' => $url_link,
'timestamp' => $timestamp,
'color' => hexdec('1b75bb'),
'footer' => [
'text' => 'Leantime',
'icon_url' => $url_link,
],
'author' => [
'name' => $this->projectName,
'url' => $url_link,
],
'title' => $notification->message,
'url' => $url_link,
'timestamp' => date('c', strtotime('now')),
'fields' => $fields,
],
]
],

], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

try {
Expand Down Expand Up @@ -282,23 +276,27 @@ public function prepareMessage(NotificationModel $notification): array
$headline = $notification->entity->headline;
$status = $notification->entity->status;
}

$fields = [
'title' => $this->language->__("headlines.project_with_name") . ' ' . $this->projectName,
'short' => false,
];

$statusLabelsArray = $ticketService->getStatusLabels($notification->projectId);
$message = array(
if (!empty($statusLabelsArray[$status])) {
$fields['value'] = $this->language->__("label.todo_status") . ': '. $statusLabelsArray[$status]['name'];
}

$message = [
[
'color' => '#1b75bb',
'fallback' => $notification->message,
'pretext' => $notification->message,
'title' => $headline,
'title_link' => $notification->url['url'],
'fields' => array(
[
'title' => $this->language->__("headlines.project_with_name") . ' ' . $this->projectName,
'value' => $this->language->__("label.todo_status") . ': ' . empty($statusLabelsArray[$status]) ? '' : $statusLabelsArray[$status]['name'],
'short' => false,
],
),
'fields' => $fields,
],
);
];

return $message;
}
Expand Down
1 change: 1 addition & 0 deletions app/Domain/Tickets/Repositories/Tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ public function simpleTicketQuery(?int $userId, ?int $projectId): array|false
IF(zp_tickets.type <> "", zp_tickets.type, "task") AS type,
zp_tickets.status,
zp_tickets.tags,
zp_tickets.userId,
zp_tickets.editorId,
zp_tickets.dependingTicketId,
zp_tickets.milestoneid,
Expand Down
48 changes: 46 additions & 2 deletions app/Domain/Tickets/Services/Tickets.php
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,48 @@ public function getOpenUserTicketsByProject($userId, $projectId): array
return $tickets;
}

/**
* @param $userId
* @param $projectId
* @return array
*/
public function getOpenUserTicketsByPriority($userId, $projectId): array
{

$searchCriteria = $this->prepareTicketSearchArray(array("users" => $userId, "status" => "", "sprint" => ""));
$allTickets = $this->ticketRepository->getAllBySearchCriteria($searchCriteria, "priority");

$statusLabels = $this->getAllStatusLabelsByUserId($userId);

$tickets = array();

foreach ($allTickets as $row) {
//Only include todos that are not done
if (
isset($statusLabels[$row['projectId']]) &&
isset($statusLabels[$row['projectId']][$row['status']]) &&
$statusLabels[$row['projectId']][$row['status']]['statusType'] != "DONE"
) {
$label = $this->ticketRepository->priority[$row['priority']];
if (isset($tickets[$row['priority']])) {
$tickets[$row['priority']]['tickets'][] = $row;
} else {
// If the priority is not set, the label for priority not defined is used.
if (empty($this->ticketRepository->priority[$row['priority']])) {
$label =$this->language->__("label.priority_not_defined");
}
$tickets[$row['priority']] = array(
"labelName" =>$label,
"tickets" => array($row),
"groupValue" => $row['time'],
);
}
}
}

return $tickets;
}


/**
* @param $userId
Expand Down Expand Up @@ -1085,7 +1127,7 @@ public function quickAddTicket($params): array|bool

$values = array(
'headline' => $params['headline'],
'type' => 'Task',
'type' => 'task',
'description' => $params['description'] ?? '',
'projectId' => $params['projectId'] ?? session("currentProject"),
'editorId' => session("userdata.id"),
Expand Down Expand Up @@ -1193,7 +1235,7 @@ public function addTicket($values)
$values = array(
'id' => '',
'headline' => $values['headline'] ?? "",
'type' => $values['type'] ?? "Task",
'type' => $values['type'] ?? "task",
'description' => $values['description'] ?? "",
'projectId' => $values['projectId'] ?? session("currentProject") ,
'editorId' => $values['editorId'] ?? "",
Expand Down Expand Up @@ -1941,6 +1983,8 @@ public function getToDoWidgetAssignments($params)
$tickets = $this->getOpenUserTicketsThisWeekAndLater(session("userdata.id"), $projectFilter);
} elseif ($groupBy == "project") {
$tickets = $this->getOpenUserTicketsByProject(session("userdata.id"), $projectFilter);
} elseif ($groupBy == "priority") {
$tickets = $this->getOpenUserTicketsByPriority(session("userdata.id"), $projectFilter);
} elseif ($groupBy == "sprint") {
$tickets = $this->getOpenUserTicketsBySprint(session("userdata.id"), $projectFilter);
}
Expand Down
16 changes: 16 additions & 0 deletions app/Domain/Widgets/Templates/partials/myToDos.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ class="btn btn-primary"
<label for="groupByProject">{!! __("label.project") !!}</label>
</span>
</li>
<li>
<span class="radio">
<input type="radio"
name="groupBy"
@if($groupBy == "priority") checked='checked' @endif
value="priority" id="groupByPriority"
hx-get="{{BASE_URL}}/widgets/myToDos/get"
hx-trigger="click"
hx-target="#yourToDoContainer"
hx-swap="outerHTML"
hx-indicator="#todos .htmx-indicator"
hx-vals='{"projectFilter": {{ $projectFilter }}, "groupBy": "priority" }'
/>
<label for="groupByPriority">{!! __("label.priority") !!}</label>
</span>
</li>

</ul>
</div>
Expand Down
1 change: 1 addition & 0 deletions app/Language/ar-SA.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/cs-CZ.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/da-DK.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Prioritet"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/de-DE-inf.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="Liste"
groupByLabel.sprint="Liste"
groupByLabel.project="Projekt"
groupByLabel.time="Fälligkeitsdatum"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Daten"

Expand Down
1 change: 1 addition & 0 deletions app/Language/de-DE.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="Liste"
groupByLabel.sprint="Liste"
groupByLabel.project="Projekt"
groupByLabel.time="Fälligkeitsdatum"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Daten"

Expand Down
1 change: 1 addition & 0 deletions app/Language/el-GR.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/en-GB.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/en-PT.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/en-UD.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/es-419.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2391,6 +2391,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
1 change: 1 addition & 0 deletions app/Language/es-ES.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2393,6 +2393,7 @@ dropdown.choose_list="List"
groupByLabel.sprint="List"
groupByLabel.project="Project"
groupByLabel.time="Due Date"
groupByLabel.priority="Priority"

label.sprint_dates="Sprint Dates"

Expand Down
Loading

0 comments on commit e74d98d

Please sign in to comment.