Skip to content
Open
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
28 changes: 28 additions & 0 deletions app/Console/Commands/GenerateSwaggerDocs.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public function modifyOpenAPIJsonFile($filterPaths = [], $filePath = 'vendor/res

$jsonData = json_decode(File::get($jsonFilePath), true);

$this->removeInvalidResponseStatusCodes($jsonData);

// Add security to non-public paths
if (isset($jsonData['paths'])) {
foreach ($jsonData['paths'] as $pathKey => &$path) {
Expand Down Expand Up @@ -95,4 +97,30 @@ public function modifyOpenAPIJsonFile($filterPaths = [], $filePath = 'vendor/res

File::put($jsonFilePath, $updatedJsonContents);
}

/**
* Remove response keys mangled by Lomkit's array_merge (e.g. "0", "\"500\"").
*/
private function removeInvalidResponseStatusCodes(array &$jsonData): void
{
foreach ($jsonData['paths'] ?? [] as &$path) {
foreach ($path as &$operation) {
if (! is_array($operation) || ! isset($operation['responses'])) {
continue;
}

foreach (array_keys($operation['responses']) as $statusCode) {
if ($statusCode === 'default') {
continue;
}

if (! ctype_digit((string) $statusCode)) {
unset($operation['responses'][$statusCode]);
}
}
}
}

unset($path, $operation);
}
}
24 changes: 24 additions & 0 deletions app/Documentation/Schemas/Responses.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace App\Documentation\Schemas;

use Lomkit\Rest\Documentation\Schemas\Responses as BaseResponses;

class Responses extends BaseResponses
{
/**
* Preserve numeric HTTP status code keys (array_merge reindexes them to 0).
*/
public function withOthers(array $others): Responses
{
$this->others = $this->others + $others;

return $this;
}

public function jsonSerialize(): mixed
{
return ['default' => $this->default()->jsonSerialize()]
+ collect($this->others())->map->jsonSerialize()->toArray();
}
}
6 changes: 3 additions & 3 deletions app/Providers/RestDocumentationServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Providers;

use App\Documentation\Schemas\Responses;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\Features;
use Lomkit\Rest\Documentation\Schemas\Example;
Expand All @@ -13,7 +14,6 @@
use Lomkit\Rest\Documentation\Schemas\Path;
use Lomkit\Rest\Documentation\Schemas\RequestBody;
use Lomkit\Rest\Documentation\Schemas\Response;
use Lomkit\Rest\Documentation\Schemas\Responses;
use Lomkit\Rest\Documentation\Schemas\SchemaConcrete;
use Lomkit\Rest\Facades\Rest;

Expand Down Expand Up @@ -312,7 +312,7 @@ public function boot()
])
)
->withOthers([
json_encode('500') => (new Response)
'500' => (new Response)
->withDescription('Server Error')
->withContent([
'application/json' => (new MediaType)
Expand Down Expand Up @@ -422,7 +422,7 @@ public function boot()
->withDescription('Email verification successful and redirected')
)
->withOthers([
json_encode('401') => (new Response)
'401' => (new Response)
->withDescription('Invalid/Expired URL provided')
->generate(),
])
Expand Down
4 changes: 2 additions & 2 deletions app/Support/Csp/Policies/CoconutPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ public function configure(Policy $policy): void
$policy
->add(Directive::SCRIPT, Keyword::SELF)
->add(Directive::STYLE, Keyword::SELF)
->add(Directive::FONT, [Keyword::SELF, 'data:'])
->add(Directive::FONT, [Keyword::SELF, 'data:', 'https://fonts.scalar.com'])
->add(Directive::CONNECT, Keyword::SELF);

// Third-party services
$policy
->add(Directive::STYLE, ['https://fonts.googleapis.com', 'https://unpkg.com', 'https://cdn.jsdelivr.net', 'https://fonts.bunny.net'])
->add(Directive::FONT, ['https://fonts.bunny.net'])
->add(Directive::SCRIPT, ['https://matomo.nfdi4chem.de', 'https://cdn.jsdelivr.net', 'https://unpkg.com'])
->add(Directive::CONNECT, ['https://matomo.nfdi4chem.de', 'https://unpkg.com'])
->add(Directive::CONNECT, ['https://matomo.nfdi4chem.de', 'https://unpkg.com', 'https://fonts.scalar.com'])
->add(Directive::IMG, 'https://matomo.nfdi4chem.de');

// Add Coconut-specific external sources
Expand Down
2 changes: 1 addition & 1 deletion docs/api-documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ POST /api/auth/login
```

:::info
The token is of **Bearer** type. This has to be supplied in the headers of the requests. In case you are using the [swagger UI of the API](https://coconut.naturalproducts.net/api-documentation), click on the **Authorize** button and provide the token as per the instruction.
The token is of **Bearer** type. This has to be supplied in the headers of the requests. In case you are using the [interactive API documentation](https://coconut.naturalproducts.net/api-documentation), open **Authentication** and provide the token as per the instruction.
:::
### Logout
```
Expand Down
127 changes: 105 additions & 22 deletions public/vendor/rest/openapi.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"openapi": "3.1.0",
"info": {
"title": "COCONUT",
"title": "Laravel",
"summary": "COlleCtion of Open NatUral producTs",
"description": "A comprehensive platform facilitating natural product research by providing data, tools, and services for deposition, curation, and reuse.",
"contact": {
"name": "COCONUT",
"name": "Laravel",
"url": "https:\/\/coconut.naturalproducts.net\/",
"email": "info.coconut@uni-jena.de"
},
Expand Down Expand Up @@ -629,10 +629,10 @@
"application\/json": {
"example": {
"data": {
"title": "Est consectetur labore ut.",
"description": "Distinctio assumenda eum itaque veritatis in aut. Rem aut exercitationem occaecati rerum quo. Illo veritatis aut non non. Quia ipsum doloribus fugiat vel corrupti fugit quasi.",
"url": "http:\/\/crooks.com\/",
"identifier": null
"title": "Alias eos provident aperiam animi.",
"description": "Veritatis mollitia nesciunt et omnis magni. Quas est iusto natus repudiandae dolore cupiditate ratione. Enim adipisci dolores ipsa ut magnam. Ratione qui qui vel quisquam architecto.",
"url": "http:\/\/www.jaskolski.net\/quod-voluptates-tempore-qui-culpa-dolor-nobis",
"identifier": "Tempora placeat assumenda dolor at."
},
"meta": []
}
Expand Down Expand Up @@ -674,9 +674,9 @@
"application\/json": {
"example": {
"data": {
"title": "Et alias rerum incidunt et.",
"description": "Libero nesciunt placeat magnam sint. Ut in voluptas consequatur. Laborum aspernatur sint ut optio. Voluptatem illo distinctio culpa laborum.",
"url": "http:\/\/kutch.com\/ab-voluptatem-consequatur-minus-voluptas-repudiandae-perferendis",
"title": "Quos voluptatem voluptas in nemo eveniet.",
"description": "Quam est maxime nihil ut reiciendis rerum. Et et facilis et ea debitis maiores voluptate. Eum saepe ipsam libero dolor.",
"url": "https:\/\/www.green.com\/aperiam-voluptatum-dolor-fugit-similique-possimus-aut-aut",
"identifier": null
},
"meta": []
Expand Down Expand Up @@ -946,9 +946,9 @@
"application\/json": {
"example": {
"data": {
"doi": "10.1016\/j.bbrep.2025.102032~58",
"title": "RNA signaling in medicinal plants: An overlooked mechanism for phytochemical regulation.",
"authors": "Alum EU, Udechukwu CD, Obasi DC.",
"doi": "10.1007\/s11013-026-09992-1~86",
"title": "W\u00e8r\u00e8 and the Ontological Politics of Global Mental Health: Distributed Cognition in Yor\u00f9b\u00e1 Traditional Medicine.",
"authors": "Jegede O.",
"citation_text": ""
},
"meta": []
Expand Down Expand Up @@ -991,9 +991,9 @@
"application\/json": {
"example": {
"data": {
"doi": "10.1039\/b700306b~29",
"title": "Natural product isolation.",
"authors": "Sticher O.",
"doi": "10.1021\/acs.jnatprod.6c00295~37",
"title": "Systematic Assessment of the Impact of Targeted Selection Methods and Environment-Mimicking Culture Conditions on Fungal Natural Product Libraries.",
"authors": "Ness M, Wendt KL, Peramuna T, Tillery DI, Murray JE, Cichewicz RH, McCall LI.",
"citation_text": ""
},
"meta": []
Expand Down Expand Up @@ -1568,8 +1568,8 @@
"application\/json": {
"example": {
"data": {
"name": "Annabel Medhurst",
"email": "veum.adolphus@example.com"
"name": "Prof. Payton Wiza Sr.",
"email": "cronin.matilde@example.com"
},
"meta": []
}
Expand Down Expand Up @@ -1611,8 +1611,8 @@
"application\/json": {
"example": {
"data": {
"name": "Dr. Gonzalo Simonis II",
"email": "ssimonis@example.net"
"name": "Lloyd Wuckert",
"email": "vtreutel@example.org"
},
"meta": []
}
Expand Down Expand Up @@ -2535,7 +2535,8 @@
"title",
"evidence",
"comment",
"suggested_changes"
"suggested_changes",
"mol_ids"
],
"scout_fields": [],
"limits": [
Expand Down Expand Up @@ -2654,6 +2655,11 @@
"field": "suggested_changes",
"operator": "=",
"value": ""
},
{
"field": "mol_ids",
"operator": "=",
"value": ""
}
],
"sorts": [
Expand All @@ -2668,6 +2674,10 @@
{
"field": "comment",
"direction": "desc"
},
{
"field": "mol_ids",
"direction": "desc"
}
],
"selects": [
Expand All @@ -2682,6 +2692,9 @@
},
{
"field": "suggested_changes"
},
{
"field": "mol_ids"
}
],
"includes": [],
Expand Down Expand Up @@ -2742,7 +2755,8 @@
"title": "",
"evidence": "",
"comment": "",
"suggested_changes": ""
"suggested_changes": "",
"mol_ids": ""
},
"relations": []
}
Expand Down Expand Up @@ -3035,7 +3049,7 @@
}
}
},
"\"500\"": {
"500": {
"description": "Server Error",
"content": {
"application\/json": {
Expand Down Expand Up @@ -3063,6 +3077,75 @@
}
}
}
},
"\/api\/auth\/verify\/{user_id}": {
"get": {
"tags": [
"Authentication"
],
"summary": "Email verification endpoint",
"responses": {
"default": {
"description": "Email verification successful and redirected",
"headers": {
"Location": {
"description": "URL to redirect to",
"schema": {
"type": "string"
}
},
"Http-Response-Code": {
"description": "HTTP Response Code",
"schema": {
"type": "integer"
}
}
}
},
"401": {
"description": "Invalid\/Expired URL provided"
}
},
"requestBody": {
"content": {
"application\/json": {
"example": {
"user": {
"id": "example_user_id",
"name": "example_name",
"email": "example_email",
"password": "example_password"
},
"signature": "example_signature"
}
}
},
"description": "User object and Request Signature"
},
"security": [
{
"sanctum": []
}
]
}
},
"\/api\/auth\/email\/resend": {
"get": {
"tags": [
"Authentication"
],
"summary": "Resend email verification endpoint",
"responses": {
"default": {
"description": "Email verification link sent to your email address"
}
},
"security": [
{
"sanctum": []
}
]
}
}
},
"servers": [
Expand Down
Loading
Loading