create-berna-stencil 2.4.3 → 2.5.0

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.
Files changed (171) hide show
  1. package/README.md +1 -1
  2. package/bin/create.js +1 -1
  3. package/docs/Backend.md +33 -8
  4. package/nginx.conf +27 -3
  5. package/package.json +1 -1
  6. package/src/backend/_core/index.php +23 -6
  7. package/src/backend/_core/vendor/composer/autoload_static.php +10 -10
  8. package/src/backend/_core/vendor/composer/installed.json +6 -6
  9. package/src/backend/_core/vendor/composer/installed.php +2 -2
  10. package/src/backend/_core/vendor/graham-campbell/result-type/LICENSE +21 -21
  11. package/src/backend/_core/vendor/graham-campbell/result-type/composer.json +33 -33
  12. package/src/backend/_core/vendor/graham-campbell/result-type/src/Error.php +121 -121
  13. package/src/backend/_core/vendor/graham-campbell/result-type/src/Result.php +69 -69
  14. package/src/backend/_core/vendor/graham-campbell/result-type/src/Success.php +120 -120
  15. package/src/backend/_core/vendor/phpoption/phpoption/LICENSE +200 -200
  16. package/src/backend/_core/vendor/phpoption/phpoption/composer.json +50 -50
  17. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php +175 -175
  18. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/None.php +136 -136
  19. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Option.php +434 -434
  20. package/src/backend/_core/vendor/phpoption/phpoption/src/PhpOption/Some.php +169 -169
  21. package/src/backend/_core/vendor/symfony/polyfill-ctype/Ctype.php +232 -232
  22. package/src/backend/_core/vendor/symfony/polyfill-ctype/LICENSE +19 -19
  23. package/src/backend/_core/vendor/symfony/polyfill-ctype/README.md +12 -12
  24. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap.php +50 -50
  25. package/src/backend/_core/vendor/symfony/polyfill-ctype/bootstrap80.php +46 -46
  26. package/src/backend/_core/vendor/symfony/polyfill-ctype/composer.json +38 -38
  27. package/src/backend/_core/vendor/symfony/polyfill-mbstring/LICENSE +19 -19
  28. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Mbstring.php +1077 -1077
  29. package/src/backend/_core/vendor/symfony/polyfill-mbstring/README.md +13 -13
  30. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php +119 -119
  31. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +1397 -1397
  32. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +5 -5
  33. package/src/backend/_core/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php +1489 -1489
  34. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap.php +171 -171
  35. package/src/backend/_core/vendor/symfony/polyfill-mbstring/bootstrap80.php +167 -167
  36. package/src/backend/_core/vendor/symfony/polyfill-mbstring/composer.json +39 -39
  37. package/src/backend/_core/vendor/symfony/polyfill-php80/LICENSE +19 -19
  38. package/src/backend/_core/vendor/symfony/polyfill-php80/Php80.php +115 -115
  39. package/src/backend/_core/vendor/symfony/polyfill-php80/PhpToken.php +106 -106
  40. package/src/backend/_core/vendor/symfony/polyfill-php80/README.md +25 -25
  41. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +31 -31
  42. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +16 -16
  43. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php +20 -20
  44. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php +16 -16
  45. package/src/backend/_core/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php +16 -16
  46. package/src/backend/_core/vendor/symfony/polyfill-php80/bootstrap.php +42 -42
  47. package/src/backend/_core/vendor/symfony/polyfill-php80/composer.json +37 -37
  48. package/src/backend/_core/vendor/vlucas/phpdotenv/LICENSE +30 -30
  49. package/src/backend/_core/vendor/vlucas/phpdotenv/composer.json +60 -60
  50. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Dotenv.php +267 -267
  51. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php +12 -12
  52. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidEncodingException.php +12 -12
  53. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php +12 -12
  54. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php +12 -12
  55. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php +12 -12
  56. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Loader.php +48 -48
  57. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php +20 -20
  58. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Loader/Resolver.php +65 -65
  59. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Entry.php +59 -59
  60. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php +299 -299
  61. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lexer.php +58 -58
  62. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Lines.php +127 -127
  63. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Parser.php +53 -53
  64. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php +19 -19
  65. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Parser/Value.php +88 -88
  66. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php +15 -15
  67. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php +89 -89
  68. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php +80 -80
  69. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php +88 -88
  70. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php +85 -85
  71. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php +110 -110
  72. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php +48 -48
  73. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php +64 -64
  74. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php +91 -91
  75. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php +17 -17
  76. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php +104 -104
  77. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php +88 -88
  78. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php +27 -27
  79. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/AdapterRepository.php +107 -107
  80. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php +272 -272
  81. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php +51 -51
  82. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Paths.php +44 -44
  83. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/File/Reader.php +81 -81
  84. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/FileStore.php +72 -72
  85. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php +141 -141
  86. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php +17 -17
  87. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Store/StringStore.php +37 -37
  88. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Regex.php +112 -112
  89. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Util/Str.php +108 -108
  90. package/src/backend/_core/vendor/vlucas/phpdotenv/src/Validator.php +207 -207
  91. package/src/backend/config.example.php +13 -4
  92. package/src/frontend/data/site.json +43 -43
  93. package/src/backend/_core/vendor/graham-campbell/result-type/.gitattributes +0 -9
  94. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CODE_OF_CONDUCT.md +0 -132
  95. package/src/backend/_core/vendor/graham-campbell/result-type/.github/CONTRIBUTING.md +0 -31
  96. package/src/backend/_core/vendor/graham-campbell/result-type/.github/FUNDING.yml +0 -2
  97. package/src/backend/_core/vendor/graham-campbell/result-type/.github/SECURITY.md +0 -14
  98. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/stale.yml +0 -11
  99. package/src/backend/_core/vendor/graham-campbell/result-type/.github/workflows/tests.yml +0 -40
  100. package/src/backend/_core/vendor/graham-campbell/result-type/CHANGELOG.md +0 -53
  101. package/src/backend/_core/vendor/graham-campbell/result-type/README.md +0 -42
  102. package/src/backend/_core/vendor/graham-campbell/result-type/phpunit.xml.dist +0 -13
  103. package/src/backend/_core/vendor/graham-campbell/result-type/tests/ResultTest.php +0 -95
  104. package/src/backend/_core/vendor/phpoption/phpoption/.gitattributes +0 -13
  105. package/src/backend/_core/vendor/phpoption/phpoption/.github/CODE_OF_CONDUCT.md +0 -132
  106. package/src/backend/_core/vendor/phpoption/phpoption/.github/CONTRIBUTING.md +0 -30
  107. package/src/backend/_core/vendor/phpoption/phpoption/.github/FUNDING.yml +0 -2
  108. package/src/backend/_core/vendor/phpoption/phpoption/.github/SECURITY.md +0 -14
  109. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/static.yml +0 -40
  110. package/src/backend/_core/vendor/phpoption/phpoption/.github/workflows/tests.yml +0 -40
  111. package/src/backend/_core/vendor/phpoption/phpoption/Makefile +0 -17
  112. package/src/backend/_core/vendor/phpoption/phpoption/README.md +0 -201
  113. package/src/backend/_core/vendor/phpoption/phpoption/phpstan-baseline.neon +0 -44
  114. package/src/backend/_core/vendor/phpoption/phpoption/phpstan.neon.dist +0 -7
  115. package/src/backend/_core/vendor/phpoption/phpoption/phpunit.xml.dist +0 -13
  116. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/EnsureTest.php +0 -72
  117. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/LazyOptionTest.php +0 -357
  118. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/NoneTest.php +0 -153
  119. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/OptionTest.php +0 -166
  120. package/src/backend/_core/vendor/phpoption/phpoption/tests/PhpOption/Tests/SomeTest.php +0 -194
  121. package/src/backend/_core/vendor/phpoption/phpoption/tests/bootstrap.php +0 -8
  122. package/src/backend/_core/vendor/phpoption/phpoption/vendor-bin/phpstan/composer.json +0 -8
  123. package/src/backend/_core/vendor/vlucas/phpdotenv/.editorconfig +0 -15
  124. package/src/backend/_core/vendor/vlucas/phpdotenv/.gitattributes +0 -15
  125. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CODE_OF_CONDUCT.md +0 -132
  126. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/CONTRIBUTING.md +0 -30
  127. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/FUNDING.yml +0 -2
  128. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/SECURITY.md +0 -14
  129. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/static.yml +0 -40
  130. package/src/backend/_core/vendor/vlucas/phpdotenv/.github/workflows/tests.yml +0 -70
  131. package/src/backend/_core/vendor/vlucas/phpdotenv/Makefile +0 -17
  132. package/src/backend/_core/vendor/vlucas/phpdotenv/README.md +0 -370
  133. package/src/backend/_core/vendor/vlucas/phpdotenv/UPGRADING.md +0 -196
  134. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan-baseline.neon +0 -157
  135. package/src/backend/_core/vendor/vlucas/phpdotenv/phpstan.neon.dist +0 -7
  136. package/src/backend/_core/vendor/vlucas/phpdotenv/phpunit.xml.dist +0 -13
  137. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/DotenvTest.php +0 -387
  138. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Loader/LoaderTest.php +0 -86
  139. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/EntryParserTest.php +0 -234
  140. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LexerTest.php +0 -40
  141. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/LinesTest.php +0 -53
  142. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Parser/ParserTest.php +0 -98
  143. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ArrayAdapterTest.php +0 -57
  144. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/EnvConstAdapterTest.php +0 -75
  145. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/PutenvAdapterTest.php +0 -52
  146. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/Adapter/ServerConstAdapterTest.php +0 -75
  147. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Repository/RepositoryTest.php +0 -305
  148. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/Store/StoreTest.php +0 -141
  149. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/Dotenv/ValidatorTest.php +0 -479
  150. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/.env +0 -5
  151. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/assertions.env +0 -18
  152. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/booleans.env +0 -33
  153. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/commented.env +0 -15
  154. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/empty.env +0 -1
  155. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/example.env +0 -1
  156. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/exported.env +0 -7
  157. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/immutable.env +0 -1
  158. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/integers.env +0 -17
  159. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/large.env +0 -2
  160. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multibyte.env +0 -3
  161. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiline.env +0 -14
  162. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/multiple.env +0 -4
  163. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/mutable.env +0 -1
  164. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/nested.env +0 -15
  165. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/quoted.env +0 -11
  166. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/specialchars.env +0 -8
  167. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/unicodevarnames.env +0 -2
  168. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/utf8-with-bom-encoding.env +0 -3
  169. package/src/backend/_core/vendor/vlucas/phpdotenv/tests/fixtures/env/windows.env +0 -1
  170. package/src/backend/_core/vendor/vlucas/phpdotenv/vendor-bin/phpstan/composer.json +0 -15
  171. package/src/backend/config.php +0 -19
package/README.md CHANGED
@@ -12,7 +12,7 @@ Building a website from scratch involves a lot of moving parts: templating engin
12
12
  - 📁 **Scalable structure** — a clean, opinionated project layout that grows with your needs
13
13
  - 🌍 **Open source** — free to use, free to modify, free to share
14
14
 
15
- ![Version](https://img.shields.io/badge/version-2.4.3-blue)
15
+ ![Version](https://img.shields.io/badge/version-2.5.0-blue)
16
16
  ![License](https://img.shields.io/badge/license-Apache--2.0-blue)
17
17
  ![Eleventy](https://img.shields.io/badge/11ty-v3.1.2-black)
18
18
 
package/bin/create.js CHANGED
@@ -121,7 +121,7 @@ src/backend/config.php
121
121
 
122
122
  const PROJECT_PACKAGE = {
123
123
  name: path.basename(targetDir),
124
- version: '2.4.3',
124
+ version: '2.5.0',
125
125
  private: true,
126
126
  outputDir: 'out',
127
127
  "scripts": {
package/docs/Backend.md CHANGED
@@ -32,13 +32,23 @@ Copy `config.example.php` to `config.php` and fill in your values:
32
32
  ### config.php <small>(`src/backend/`)</small>
33
33
  ```php
34
34
  return [
35
- // Default key for protected endpoints that don't have a specific key in ENDPOINT_KEYS
36
- 'API_KEY' => 'default-key',
35
+ // Default key for protected endpoints that don't have a specific key in CUSTOM_ENDPOINT_KEYS
36
+ 'GENERAL_API_KEY' => 'default-key',
37
37
 
38
- // If you want restrict access to protected endpoints to specific clients, you can define custom keys for each endpoint
39
- 'ENDPOINT_KEYS' => [
40
- // For subfolder endpoints, use the relative path ('subfolder/endpoint')
41
- // 'subfolder/endpoint' => 'example-key',
38
+ // Per-endpoint keys. For subfolder endpoints, use the relative path ('subfolder/endpoint')
39
+ 'CUSTOM_ENDPOINT_KEYS' => [
40
+ // 'subfolder/endpoint' => 'example-key',
41
+ ],
42
+
43
+ // Default CORS origins applied to every endpoint
44
+ 'GENERAL_ALLOWED_ORIGINS' => [
45
+ 'https://example.com',
46
+ ],
47
+
48
+ // Per-endpoint CORS origins. Same path format as CUSTOM_ENDPOINT_KEYS.
49
+ // When an endpoint is listed here, these origins replace GENERAL_ALLOWED_ORIGINS for it.
50
+ 'CUSTOM_ENDPOINT_ORIGINS' => [
51
+ // 'subfolder/endpoint' => ['https://app.example.com'],
42
52
  ],
43
53
 
44
54
  'DB_HOST' => '127.0.0.1',
@@ -48,7 +58,22 @@ return [
48
58
  ];
49
59
  ```
50
60
 
51
- `API_KEY` is the fallback key for all protected endpoints. Use `ENDPOINT_KEYS` to assign a different key to a specific endpoint — for subfolder endpoints, use the relative path as the key.
61
+ ### API keys
62
+
63
+ `GENERAL_API_KEY` is the fallback key for all protected endpoints. Use `CUSTOM_ENDPOINT_KEYS` to assign a different key to a specific endpoint — for subfolder endpoints, use the relative path as the key.
64
+
65
+ > ⚠️ The API key travels in the `X-Api-Key` header on every request. Use it only for server-to-server calls over HTTPS. Never embed it in frontend code, where it would be publicly visible.
66
+
67
+ ### CORS (allowed origins)
68
+
69
+ Cross-origin access mirrors the API-key model:
70
+
71
+ - `GENERAL_ALLOWED_ORIGINS` — the default list of origins allowed to call any endpoint from a browser.
72
+ - `CUSTOM_ENDPOINT_ORIGINS` — overrides the default for a specific endpoint, keyed by the same relative path used in `CUSTOM_ENDPOINT_KEYS`.
73
+
74
+ Origins must be exact (scheme + host, no trailing slash), e.g. `https://example.com`. When a request's `Origin` is in the resolved list, it is reflected back in `Access-Control-Allow-Origin` (with `Vary: Origin`). An empty list sends no CORS header — the most restrictive setting; same-origin requests still work. Use `'*'` as the only element to allow any origin (not recommended for protected endpoints).
75
+
76
+ Resolution order for a given endpoint: `CUSTOM_ENDPOINT_ORIGINS[path]` if present, otherwise `GENERAL_ALLOWED_ORIGINS`.
52
77
 
53
78
  ## How routing works
54
79
 
@@ -102,7 +127,7 @@ Response::success(['visits' => 1024]);
102
127
  To assign a dedicated key, add it to `config.php`:
103
128
 
104
129
  ```php
105
- 'ENDPOINT_KEYS' => [
130
+ 'CUSTOM_ENDPOINT_KEYS' => [
106
131
  'endpoint' => 'custom-key',
107
132
  ],
108
133
  ```
package/nginx.conf CHANGED
@@ -1,3 +1,4 @@
1
+ # Redirect all HTTP traffic to HTTPS
1
2
  server {
2
3
  listen 80;
3
4
  server_name _;
@@ -8,12 +9,21 @@ server {
8
9
  listen 443 ssl;
9
10
  server_name _;
10
11
 
11
- # ssl_certificate /path/to/cert.pem;
12
- # ssl_certificate_key /path/to/key.pem;
12
+ # SSL certificate — replace with your own paths.
13
+ # Let's Encrypt default shown below; adjust the domain.
14
+ ssl_certificate /etc/letsencrypt/live/your-domain/fullchain.pem;
15
+ ssl_certificate_key /etc/letsencrypt/live/your-domain/privkey.pem;
16
+
17
+ # Hide the nginx version from response headers
18
+ server_tokens off;
19
+
20
+ # Force HTTPS on future requests (applies site-wide, including /api)
21
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
13
22
 
14
23
  root /var/www/html/out;
15
24
  index index.html;
16
25
 
26
+ # Disable directory listing
17
27
  autoindex off;
18
28
 
19
29
  error_page 403 404 /404.html;
@@ -21,25 +31,39 @@ server {
21
31
  internal;
22
32
  }
23
33
 
34
+ # Never expose the backend source directory
24
35
  location ^~ /backend/ {
25
36
  return 404;
26
37
  }
27
38
 
28
- location ~* ^/(web\.config|llms\.txt|robots\.txt|sitemap\.xml)$ {
39
+ # Block server config files anywhere in the tree (.htaccess, web.config).
40
+ # return 404 is served internally as /404.html via error_page above.
41
+ location ~* (^|/)(\.htaccess|web\.config)$ {
29
42
  return 404;
30
43
  }
31
44
 
45
+ # Block dotfiles (.git, .env, etc.)
32
46
  location ~ /\. {
33
47
  return 404;
34
48
  }
35
49
 
50
+ # Route all /api/ requests to the PHP front controller.
51
+ # Security headers for API responses are set by the front controller (PHP).
36
52
  location ^~ /api/ {
53
+ try_files $uri =404;
37
54
  fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
38
55
  fastcgi_param SCRIPT_FILENAME $document_root/backend/_core/index.php;
39
56
  include fastcgi_params;
40
57
  }
41
58
 
59
+ # Serve static files, fall back to the 404 page.
60
+ # A location with add_header does not inherit server-level headers,
61
+ # so Strict-Transport-Security is repeated here.
42
62
  location / {
63
+ add_header X-Content-Type-Options "nosniff" always;
64
+ add_header X-Frame-Options "SAMEORIGIN" always;
65
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
66
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
43
67
  try_files $uri $uri/ /404.html;
44
68
  }
45
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-berna-stencil",
3
- "version": "2.4.3",
3
+ "version": "2.5.0",
4
4
  "description": "Eleventy boilerplate with per-page SCSS/JS pipeline, esbuild bundling, multi-framework CSS support and a built-in page management CLI",
5
5
  "keywords": [],
6
6
  "author": "Michele Garofalo",
@@ -87,14 +87,34 @@ if (!$endpointFile) {
87
87
  exit;
88
88
  }
89
89
 
90
+ $base = $isProtected ? $baseProtected : $basePublic;
91
+ $base = str_replace('\\', '/', $base);
92
+ $endpointPath = str_replace('\\', '/', $endpointFile);
93
+ $endpointPath = preg_replace('#\.php$#', '', str_replace($base, '', $endpointPath));
94
+
90
95
  // =====================================================
91
96
  // 3. HEADERS AND CORS (Only if the endpoint exists)
92
97
  // =====================================================
93
98
 
94
99
  header('Content-Type: application/json; charset=UTF-8');
100
+ header('X-Content-Type-Options: nosniff');
101
+ header('X-Frame-Options: DENY');
102
+ header('Referrer-Policy: strict-origin-when-cross-origin');
95
103
  header('Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS');
96
104
  header('Access-Control-Allow-Headers: Content-Type, X-Api-Key');
97
- header('Access-Control-Allow-Origin: *');
105
+
106
+ $originsForEndpoint = $config['CUSTOM_ENDPOINT_ORIGINS'][$endpointPath]
107
+ ?? $config['GENERAL_ALLOWED_ORIGINS']
108
+ ?? [];
109
+
110
+ $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
111
+
112
+ if ($origin !== '' && in_array($origin, $originsForEndpoint, true)) {
113
+ header('Access-Control-Allow-Origin: ' . $origin);
114
+ header('Vary: Origin');
115
+ } elseif (in_array('*', $originsForEndpoint, true)) {
116
+ header('Access-Control-Allow-Origin: *');
117
+ }
98
118
 
99
119
  if ($method === 'OPTIONS') {
100
120
  http_response_code(204);
@@ -109,11 +129,8 @@ RateLimiter::check($_SERVER['REMOTE_ADDR'] ?? '', 60, 60);
109
129
  // =====================================================
110
130
 
111
131
  if ($isProtected) {
112
- $relPath = str_replace($baseProtected, '', $endpointFile);
113
- $relPath = str_replace('.php', '', str_replace('\\', '/', $relPath));
114
-
115
- $validKey = $config['ENDPOINT_KEYS'][$relPath] ?? $config['API_KEY'] ?? '';
116
- $apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
132
+ $validKey = $config['CUSTOM_ENDPOINT_KEYS'][$endpointPath] ?? $config['GENERAL_API_KEY'] ?? '';
133
+ $apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
117
134
 
118
135
  if ($validKey === '' || !hash_equals($validKey, $apiKey)) {
119
136
  Response::error('Unauthorized. X_API_KEY is incorrect or missing', 401);
@@ -13,48 +13,48 @@ class ComposerStaticInit108be68e4e2b97fed51d36a10eed0849
13
13
  );
14
14
 
15
15
  public static $prefixLengthsPsr4 = array (
16
- 'S' =>
16
+ 'S' =>
17
17
  array (
18
18
  'Symfony\\Polyfill\\Php80\\' => 23,
19
19
  'Symfony\\Polyfill\\Mbstring\\' => 26,
20
20
  'Symfony\\Polyfill\\Ctype\\' => 23,
21
21
  ),
22
- 'P' =>
22
+ 'P' =>
23
23
  array (
24
24
  'PhpOption\\' => 10,
25
25
  ),
26
- 'G' =>
26
+ 'G' =>
27
27
  array (
28
28
  'GrahamCampbell\\ResultType\\' => 26,
29
29
  ),
30
- 'D' =>
30
+ 'D' =>
31
31
  array (
32
32
  'Dotenv\\' => 7,
33
33
  ),
34
34
  );
35
35
 
36
36
  public static $prefixDirsPsr4 = array (
37
- 'Symfony\\Polyfill\\Php80\\' =>
37
+ 'Symfony\\Polyfill\\Php80\\' =>
38
38
  array (
39
39
  0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
40
40
  ),
41
- 'Symfony\\Polyfill\\Mbstring\\' =>
41
+ 'Symfony\\Polyfill\\Mbstring\\' =>
42
42
  array (
43
43
  0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
44
44
  ),
45
- 'Symfony\\Polyfill\\Ctype\\' =>
45
+ 'Symfony\\Polyfill\\Ctype\\' =>
46
46
  array (
47
47
  0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
48
48
  ),
49
- 'PhpOption\\' =>
49
+ 'PhpOption\\' =>
50
50
  array (
51
51
  0 => __DIR__ . '/..' . '/phpoption/phpoption/src/PhpOption',
52
52
  ),
53
- 'GrahamCampbell\\ResultType\\' =>
53
+ 'GrahamCampbell\\ResultType\\' =>
54
54
  array (
55
55
  0 => __DIR__ . '/..' . '/graham-campbell/result-type/src',
56
56
  ),
57
- 'Dotenv\\' =>
57
+ 'Dotenv\\' =>
58
58
  array (
59
59
  0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src',
60
60
  ),
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "time": "2025-12-27T19:43:20+00:00",
26
26
  "type": "library",
27
- "installation-source": "source",
27
+ "installation-source": "dist",
28
28
  "autoload": {
29
29
  "psr-4": {
30
30
  "GrahamCampbell\\ResultType\\": "src/"
@@ -98,7 +98,7 @@
98
98
  "dev-master": "1.9-dev"
99
99
  }
100
100
  },
101
- "installation-source": "source",
101
+ "installation-source": "dist",
102
102
  "autoload": {
103
103
  "psr-4": {
104
104
  "PhpOption\\": "src/PhpOption/"
@@ -175,7 +175,7 @@
175
175
  "name": "symfony/polyfill"
176
176
  }
177
177
  },
178
- "installation-source": "source",
178
+ "installation-source": "dist",
179
179
  "autoload": {
180
180
  "files": [
181
181
  "bootstrap.php"
@@ -262,7 +262,7 @@
262
262
  "name": "symfony/polyfill"
263
263
  }
264
264
  },
265
- "installation-source": "source",
265
+ "installation-source": "dist",
266
266
  "autoload": {
267
267
  "files": [
268
268
  "bootstrap.php"
@@ -343,7 +343,7 @@
343
343
  "name": "symfony/polyfill"
344
344
  }
345
345
  },
346
- "installation-source": "source",
346
+ "installation-source": "dist",
347
347
  "autoload": {
348
348
  "files": [
349
349
  "bootstrap.php"
@@ -447,7 +447,7 @@
447
447
  "dev-master": "5.6-dev"
448
448
  }
449
449
  },
450
- "installation-source": "source",
450
+ "installation-source": "dist",
451
451
  "autoload": {
452
452
  "psr-4": {
453
453
  "Dotenv\\": "src/"
@@ -3,7 +3,7 @@
3
3
  'name' => '__root__',
4
4
  'pretty_version' => 'dev-main',
5
5
  'version' => 'dev-main',
6
- 'reference' => '4da27b8f50bb1a801f88ad46a9e9eafa51c1bb34',
6
+ 'reference' => '9bbb36794fc27d6938523db2d4076661ad9ddab9',
7
7
  'type' => 'library',
8
8
  'install_path' => __DIR__ . '/../../',
9
9
  'aliases' => array(),
@@ -13,7 +13,7 @@
13
13
  '__root__' => array(
14
14
  'pretty_version' => 'dev-main',
15
15
  'version' => 'dev-main',
16
- 'reference' => '4da27b8f50bb1a801f88ad46a9e9eafa51c1bb34',
16
+ 'reference' => '9bbb36794fc27d6938523db2d4076661ad9ddab9',
17
17
  'type' => 'library',
18
18
  'install_path' => __DIR__ . '/../../',
19
19
  'aliases' => array(),
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2020-2024 Graham Campbell <hello@gjcampbell.co.uk>
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020-2024 Graham Campbell <hello@gjcampbell.co.uk>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -1,33 +1,33 @@
1
- {
2
- "name": "graham-campbell/result-type",
3
- "description": "An Implementation Of The Result Type",
4
- "keywords": ["result", "result-type", "Result", "Result Type", "Result-Type", "Graham Campbell", "GrahamCampbell"],
5
- "license": "MIT",
6
- "authors": [
7
- {
8
- "name": "Graham Campbell",
9
- "email": "hello@gjcampbell.co.uk",
10
- "homepage": "https://github.com/GrahamCampbell"
11
- }
12
- ],
13
- "require": {
14
- "php": "^7.2.5 || ^8.0",
15
- "phpoption/phpoption": "^1.9.5"
16
- },
17
- "require-dev": {
18
- "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7"
19
- },
20
- "autoload": {
21
- "psr-4": {
22
- "GrahamCampbell\\ResultType\\": "src/"
23
- }
24
- },
25
- "autoload-dev": {
26
- "psr-4": {
27
- "GrahamCampbell\\Tests\\ResultType\\": "tests/"
28
- }
29
- },
30
- "config": {
31
- "preferred-install": "dist"
32
- }
33
- }
1
+ {
2
+ "name": "graham-campbell/result-type",
3
+ "description": "An Implementation Of The Result Type",
4
+ "keywords": ["result", "result-type", "Result", "Result Type", "Result-Type", "Graham Campbell", "GrahamCampbell"],
5
+ "license": "MIT",
6
+ "authors": [
7
+ {
8
+ "name": "Graham Campbell",
9
+ "email": "hello@gjcampbell.co.uk",
10
+ "homepage": "https://github.com/GrahamCampbell"
11
+ }
12
+ ],
13
+ "require": {
14
+ "php": "^7.2.5 || ^8.0",
15
+ "phpoption/phpoption": "^1.9.5"
16
+ },
17
+ "require-dev": {
18
+ "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7"
19
+ },
20
+ "autoload": {
21
+ "psr-4": {
22
+ "GrahamCampbell\\ResultType\\": "src/"
23
+ }
24
+ },
25
+ "autoload-dev": {
26
+ "psr-4": {
27
+ "GrahamCampbell\\Tests\\ResultType\\": "tests/"
28
+ }
29
+ },
30
+ "config": {
31
+ "preferred-install": "dist"
32
+ }
33
+ }