create-berna-stencil 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eleventy.js +3 -1
- package/_tools/res/templates.json +2 -2
- package/bin/create.js +1 -1
- package/package.json +5 -5
- package/src/.htaccess +18 -0
- package/src/api/.htaccess +12 -0
- package/src/api/composer.json +6 -0
- package/src/api/composer.lock +574 -0
- package/src/api/endpoints/protected/secret.php +16 -0
- package/src/api/endpoints/protected/send-mail.php +75 -0
- package/src/api/endpoints/public/ping.php +16 -0
- package/src/api/index.php +95 -0
- package/src/api/init.php +43 -0
- package/src/api/modules/Response.php +37 -0
- package/src/api/vendor/autoload.php +22 -0
- package/src/api/vendor/composer/ClassLoader.php +579 -0
- package/src/api/vendor/composer/InstalledVersions.php +396 -0
- package/src/api/vendor/composer/LICENSE +21 -0
- package/src/api/vendor/composer/autoload_classmap.php +15 -0
- package/src/api/vendor/composer/autoload_files.php +12 -0
- package/src/api/vendor/composer/autoload_namespaces.php +9 -0
- package/src/api/vendor/composer/autoload_psr4.php +16 -0
- package/src/api/vendor/composer/autoload_real.php +50 -0
- package/src/api/vendor/composer/autoload_static.php +86 -0
- package/src/api/vendor/composer/installed.json +582 -0
- package/src/api/vendor/composer/installed.php +86 -0
- package/src/api/vendor/composer/platform_check.php +25 -0
- package/src/data/site.json +53 -53
- package/src/js/pages/404.js +2 -2
- package/src/js/pages/anotherPage.js +2 -2
- package/src/js/pages/homepage.js +2 -2
- package/src/scss/pages/404.scss +1 -0
- package/src/api/configExample.php +0 -28
- package/src/api/sendEmail.php +0 -131
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
declare(strict_types=1);
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Caricamento delle dipendenze e configurazione iniziale.
|
|
7
|
+
*/
|
|
8
|
+
require_once __DIR__ . '/init.php';
|
|
9
|
+
require_once __DIR__ . '/modules/Response.php';
|
|
10
|
+
|
|
11
|
+
// =====================================================
|
|
12
|
+
// 1. ANALISI DELLA RICHIESTA (REQUEST PARSING)
|
|
13
|
+
// =====================================================
|
|
14
|
+
|
|
15
|
+
$method = $_SERVER['REQUEST_METHOD'];
|
|
16
|
+
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
|
17
|
+
|
|
18
|
+
// Pulizia URI: rimuoviamo /api e eventuali slash finali
|
|
19
|
+
$uri = rtrim(preg_replace('#^/api#', '', $uri), '/') ?: '/';
|
|
20
|
+
$parts = array_values(array_filter(explode('/', $uri)));
|
|
21
|
+
|
|
22
|
+
$resource = $parts[0] ?? null;
|
|
23
|
+
|
|
24
|
+
// =====================================================
|
|
25
|
+
// 2. RISOLUZIONE ENDPOINT (ROUTING)
|
|
26
|
+
// =====================================================
|
|
27
|
+
|
|
28
|
+
$publicPath = __DIR__ . '/endpoints/public/' . $resource . '.php';
|
|
29
|
+
$protectedPath = __DIR__ . '/endpoints/protected/' . $resource . '.php';
|
|
30
|
+
|
|
31
|
+
$isPublic = $resource !== null && file_exists($publicPath);
|
|
32
|
+
$isProtected = $resource !== null && file_exists($protectedPath);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* SE L'ENDPOINT NON ESISTE (RITORNO HTML 404)
|
|
36
|
+
*/
|
|
37
|
+
if (!$isPublic && !$isProtected) {
|
|
38
|
+
http_response_code(404);
|
|
39
|
+
|
|
40
|
+
// Cerchiamo il file 404.html generato da Eleventy nella root di Laragon
|
|
41
|
+
$errorPage = $_SERVER['DOCUMENT_ROOT'] . '/404.html';
|
|
42
|
+
|
|
43
|
+
if (file_exists($errorPage)) {
|
|
44
|
+
header('Content-Type: text/html; charset=UTF-8');
|
|
45
|
+
echo file_get_contents($errorPage);
|
|
46
|
+
} else {
|
|
47
|
+
echo "<h1>404 Not Found</h1>";
|
|
48
|
+
echo "The requested URL was not found on this server.";
|
|
49
|
+
}
|
|
50
|
+
exit;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// =====================================================
|
|
54
|
+
// 3. HEADERS E CORS (Solo se l'endpoint esiste)
|
|
55
|
+
// =====================================================
|
|
56
|
+
|
|
57
|
+
header('Content-Type: application/json; charset=UTF-8');
|
|
58
|
+
header('Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS');
|
|
59
|
+
header('Access-Control-Allow-Headers: Content-Type, X-Api-Key');
|
|
60
|
+
|
|
61
|
+
$allowedOrigins = array_filter(array_map('trim', explode(',', $_ENV['CORS_ALLOWED_ORIGINS'] ?? '')));
|
|
62
|
+
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
|
|
63
|
+
|
|
64
|
+
if (in_array($origin, $allowedOrigins, true) || in_array('*', $allowedOrigins, true)) {
|
|
65
|
+
header("Access-Control-Allow-Origin: $origin");
|
|
66
|
+
} else {
|
|
67
|
+
header("Access-Control-Allow-Origin: " . ($allowedOrigins[0] ?? ''));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if ($method === 'OPTIONS') {
|
|
71
|
+
http_response_code(204);
|
|
72
|
+
exit;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// =====================================================
|
|
76
|
+
// 4. GUARDIA DI AUTENTICAZIONE
|
|
77
|
+
// =====================================================
|
|
78
|
+
|
|
79
|
+
if ($isProtected) {
|
|
80
|
+
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
|
|
81
|
+
$validKey = $_ENV['API_KEY'] ?? '';
|
|
82
|
+
|
|
83
|
+
if ($validKey === '' || $apiKey !== $validKey) {
|
|
84
|
+
Response::error('Unauthorized', 401);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// =====================================================
|
|
89
|
+
// 5. ESECUZIONE (DISPATCH)
|
|
90
|
+
// =====================================================
|
|
91
|
+
|
|
92
|
+
$requestParams = array_slice($parts, 1);
|
|
93
|
+
|
|
94
|
+
// Carica il file dell'endpoint richiesto
|
|
95
|
+
require $isProtected ? $protectedPath : $publicPath;
|
package/src/api/init.php
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
declare(strict_types=1);
|
|
4
|
+
|
|
5
|
+
require_once __DIR__ . '/vendor/autoload.php';
|
|
6
|
+
require_once __DIR__ . '/modules/Response.php';
|
|
7
|
+
|
|
8
|
+
// --- GESTORE GLOBALE ERRORI E ECCEZIONI ---
|
|
9
|
+
// Trasforma ogni errore PHP in una risposta JSON pulita
|
|
10
|
+
set_exception_handler(function ($exception) {
|
|
11
|
+
Response::error(
|
|
12
|
+
$exception->getMessage(),
|
|
13
|
+
500,
|
|
14
|
+
['file' => $exception->getFile(), 'line' => $exception->getLine()]
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
set_error_handler(function ($severity, $message, $file, $line) {
|
|
19
|
+
if (!(error_reporting() & $severity)) return;
|
|
20
|
+
throw new ErrorException($message, 0, $severity, $file, $line);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// --- CARICAMENTO DOTENV ---
|
|
24
|
+
// dirname(__DIR__, 1) sale di un livello (da api/ a Berna-Stencil-out/)
|
|
25
|
+
try {
|
|
26
|
+
$dotenv = Dotenv\Dotenv::createImmutable(dirname(__DIR__, 1));
|
|
27
|
+
$dotenv->load();
|
|
28
|
+
} catch (Exception $e) {
|
|
29
|
+
Response::error("Impossibile caricare il file .env. Assicurati che esista nella root e si chiami esattamente .env", 500);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
$dotenv->required([
|
|
33
|
+
'API_KEY',
|
|
34
|
+
'CORS_ALLOWED_ORIGINS',
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
if (($_ENV['APP_ENV'] ?? 'production') === 'production') {
|
|
38
|
+
ini_set('display_errors', '0');
|
|
39
|
+
error_reporting(0);
|
|
40
|
+
} else {
|
|
41
|
+
ini_set('display_errors', '1');
|
|
42
|
+
error_reporting(E_ALL);
|
|
43
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
declare(strict_types=1);
|
|
4
|
+
|
|
5
|
+
class Response
|
|
6
|
+
{
|
|
7
|
+
public static function success(mixed $data = null, int $code = 200): never
|
|
8
|
+
{
|
|
9
|
+
http_response_code($code);
|
|
10
|
+
echo json_encode([
|
|
11
|
+
'status' => 'success',
|
|
12
|
+
'data' => $data,
|
|
13
|
+
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
14
|
+
exit;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public static function error(string $message, int $code = 400, mixed $details = null): never
|
|
18
|
+
{
|
|
19
|
+
http_response_code($code);
|
|
20
|
+
$body = [
|
|
21
|
+
'status' => 'error',
|
|
22
|
+
'message' => $message,
|
|
23
|
+
'code' => $code,
|
|
24
|
+
];
|
|
25
|
+
if ($details !== null) {
|
|
26
|
+
$body['details'] = $details;
|
|
27
|
+
}
|
|
28
|
+
echo json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
29
|
+
exit;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public static function noContent(): never
|
|
33
|
+
{
|
|
34
|
+
http_response_code(204);
|
|
35
|
+
exit;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
// autoload.php @generated by Composer
|
|
4
|
+
|
|
5
|
+
if (PHP_VERSION_ID < 50600) {
|
|
6
|
+
if (!headers_sent()) {
|
|
7
|
+
header('HTTP/1.1 500 Internal Server Error');
|
|
8
|
+
}
|
|
9
|
+
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
|
10
|
+
if (!ini_get('display_errors')) {
|
|
11
|
+
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
|
12
|
+
fwrite(STDERR, $err);
|
|
13
|
+
} elseif (!headers_sent()) {
|
|
14
|
+
echo $err;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
throw new RuntimeException($err);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
require_once __DIR__ . '/composer/autoload_real.php';
|
|
21
|
+
|
|
22
|
+
return ComposerAutoloaderInite875ae8441d070d7dda5f4b47a2117aa::getLoader();
|