Compare commits

...
7 Commits
Author SHA1 Message Date
cd9f5783d0 Add recipe for jpmmartin/sylius-nmi-plugin (#2050)
Claude-Session: https://claude.ai/code/session_01WYGgHP9evTsmdwbszaakYL

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 17:34:54 +04:00
e2e8f5cd11 Add tailsfadmin/tailsfadmin-bundle (#2047)
* Add tailsfadmin/tailsfadmin-bundle recipe: manifest

* Add tailsfadmin recipe: default config

* Add tailsfadmin recipe: asset_mapper paths

* Post-install output in English

* English comments (default config)

* English comments (asset_mapper paths)

* Fix CI: remove unsupported alias, use 4-space indentation

- manifest.json: drop "aliases" (aliases are not supported in recipes-contrib)
- config/packages/tailsfadmin.yaml: put the menu list dash on its own line so
  every indentation level is a multiple of 4 spaces (recipes-contrib lint)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-14 17:24:32 +04:00
Igor PinchukandGitHub e5e55bbe4f Add recipe for indexnowkit/symfony-bundle (#2048) 2026-09-10 17:58:04 +04:00
Diego D'amicoandGitHub 545f6e495a Fix odiseoteam/sylius-rbac-plugin admin route prefix (#2046)
* Fix odiseoteam/sylius-rbac-plugin admin route prefix

The recipe hardcoded prefix: /admin, so on any install that customizes
SYLIUS_ADMIN_ROUTING_PATH_NAME the plugin's own admin routes land outside
sylius.security.admin_regex and are unreachable through the admin firewall.
Use the same parameterized prefix Sylius' own admin routes use.

Also trims the post-install note: the AdminUser snippet and the migration
command are already covered by the linked installation guide.

* Trigger CI
2026-09-08 17:29:05 +04:00
mrk-teandGitHub 2833906142 Add recipe for codein/recaptcha-enterprise-bundle (#2045) 2026-09-07 14:12:39 +04:00
acencyrilandGitHub 07f7809541 Add acencyril/sentinelle-bundle recipe (#2040)
* Add acencyril/sentinelle-bundle recipe

* Remove aliases, not supported in contrib

* Target 0.2

* Target 0.3, English configuration

* Add trailing newlines

* Fix indentation

* Trailing newline, remove IDE files

* Fix YAML indentation
2026-09-04 10:37:23 +04:00
Diego D'amicoandGitHub 42c7572f9a Add recipe for odiseoteam/sylius-rbac-plugin (#2044) 2026-09-04 10:32:46 +04:00
21 changed files with 256 additions and 0 deletions
@@ -0,0 +1,14 @@
sentinelle:
# Dry-run: Sentinelle detects, logs and alerts, but blocks NOTHING.
# Nobody wires automatic blocking into a production site without knowing
# what it will shut out. Watch the dashboard for a few days, ask yourself
# "would I have wanted to block that one?", then switch it off.
dry_run: true
alert:
recipient: '%env(SENTINELLE_ALERT_EMAIL)%'
access:
role: ROLE_ADMIN
never_block:
# At minimum your own outbound address. Private ranges are protected
# by default, but yours is not: one wrong move locks you out.
ips: '%env(default::SENTINELLE_ALLOWLIST)%'
@@ -0,0 +1,3 @@
sentinelle:
resource: '@SentinelleBundle/config/routes.php'
type: php
@@ -0,0 +1,40 @@
{
"bundles": {
"Acencyril\\SentinelleBundle\\SentinelleBundle": [
"all"
]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
},
"env": {
"#1": "Where security alerts are sent.",
"SENTINELLE_ALERT_EMAIL": "admin@example.com",
"#2": "IPs or CIDRs, comma separated, that must never be blocked.",
"#3": "PUT YOUR OWN OUTBOUND ADDRESS HERE before going live:",
"#4": "without it, an automatic block can lock you out of your own site.",
"SENTINELLE_ALLOWLIST": ""
},
"post-install-output": [
" <bg=blue;fg=white>Sentinelle is installed.</> Three things before going live:",
"",
" * Set <comment>SENTINELLE_ALLOWLIST</comment> in your <comment>.env</comment> — at minimum your own",
" outbound address. Without it, an automatic block can lock you out of",
" your own site.",
"",
" * Create the schema:",
" <comment>php bin/console doctrine:migrations:diff</comment>",
" <comment>php bin/console doctrine:migrations:migrate</comment>",
"",
" * Check it can do its job:",
" <comment>php bin/console sentinelle:check</comment>",
"",
" Sentinelle starts in <comment>dry-run</comment>: it detects, logs and alerts, but blocks",
" nothing. Watch <comment>/admin/activity</comment> for a few days, then set",
" <comment>sentinelle.dry_run</comment> to <comment>false</comment>.",
"",
" And schedule the purge, without which strike counters never reset:",
" <comment>0 4 * * * php bin/console sentinelle:purge</comment>",
""
]
}
@@ -0,0 +1,16 @@
codein_recaptcha_enterprise:
project_id: '%env(CODEIN_RECAPTCHA_ENTERPRISE_PROJECT_ID)%'
site_key: '%env(CODEIN_RECAPTCHA_ENTERPRISE_SITE_KEY)%'
api_key: '%env(CODEIN_RECAPTCHA_ENTERPRISE_API_KEY)%'
#challenge: checkbox # score (default) or checkbox, each needs its own kind of site key
#min_score: 0 # 0 disables the score check, which is what the checkbox challenge wants
#on_error: allow # deny (default) refuses the token when Google cannot be reached
# A test run has no browser to solve the challenge, so every submission would be refused.
when@test:
codein_recaptcha_enterprise:
enabled: false
#when@dev:
# codein_recaptcha_enterprise:
# enabled: false
@@ -0,0 +1,16 @@
{
"bundles": {
"Codein\\RecaptchaEnterpriseBundle\\CodeinRecaptchaEnterpriseBundle": ["all"]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
},
"env": {
"#1": "Create the key and read the project id in the reCAPTCHA Enterprise console:",
"#2": "https://console.cloud.google.com/security/recaptcha",
"#3": "The score and checkbox challenges each need their own kind of site key.",
"CODEIN_RECAPTCHA_ENTERPRISE_PROJECT_ID": "",
"CODEIN_RECAPTCHA_ENTERPRISE_SITE_KEY": "",
"CODEIN_RECAPTCHA_ENTERPRISE_API_KEY": ""
}
}
@@ -0,0 +1,12 @@
* <fg=blue>Set</> the <comment>CODEIN_RECAPTCHA_ENTERPRISE_*</> variables in <comment>.env.local</>
* <fg=blue>Add</> <comment>two script tags</> to your layout — the bundle adds neither. Without them every
submission is refused as <comment>MISSING</>:
<comment>{{ asset('bundles/codeinrecaptchaenterprise/recaptcha-enterprise.js') }}</>, and Google's
<comment>enterprise.js</>, the latter only <comment>after the visitor has consented</>:
<comment>https://github.com/Codein-Labs/recaptcha-enterprise-bundle#adding-the-scripts-to-your-layout</>
* <fg=blue>Read</> <comment>Choosing the challenge</> before creating the site key: the score and checkbox
challenges need different key types
* Assessments are <comment>disabled in the test environment</>, where no browser can solve the challenge
@@ -0,0 +1,3 @@
indexnowkit:
key: '%env(INDEXNOW_KEY)%'
base_url: '%env(INDEXNOW_BASE_URL)%'
@@ -0,0 +1,2 @@
indexnowkit:
resource: '@IndexNowKitBundle/config/routes.php'
@@ -0,0 +1,15 @@
{
"bundles": {
"IndexNowKit\\SymfonyBundle\\IndexNowKitBundle": ["all"]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
},
"env": {
"#1": "The IndexNow key, served at /<key>.txt. Generate one into .env.local: bin/console indexnow:key:generate --write-env",
"#2": "Empty outside production = dry run (nothing is sent); empty in production = a configuration error indexnow:check explains",
"INDEXNOW_KEY": "",
"#3": "The public URL of the site (console commands and Messenger workers have no request to read it from)",
"INDEXNOW_BASE_URL": "https://www.example.com"
}
}
@@ -0,0 +1,9 @@
<fg=blue;options=bold>IndexNow</> is installed: search engines (Yandex, Bing, Naver, Seznam, ...) get told which pages changed.
<options=bold>Next steps:</>
1. Run <comment>bin/console indexnow:key:generate --write-env</> — writes <comment>INDEXNOW_KEY</> to <comment>.env.local</>
2. Set <comment>INDEXNOW_BASE_URL</> to the public URL of the site
3. Add <comment>#[IndexNow(route: '...')]</> to the entities that have a public page (needs <comment>indexnowkit/doctrine</>)
4. Run <comment>bin/console indexnow:check</> — it verifies the key file, the transport and the configuration
Documentation: https://github.com/indexnowkit/php/tree/main/packages/symfony-bundle
@@ -0,0 +1,2 @@
imports:
- { resource: "@JpmMartinSyliusNmiPlugin/config/config.yaml" }
@@ -0,0 +1,18 @@
jpm_martin_sylius_nmi_shop:
resource: "@JpmMartinSyliusNmiPlugin/config/routes/shop.yaml"
jpm_martin_sylius_nmi_admin:
resource: "@JpmMartinSyliusNmiPlugin/config/routes/admin.yaml"
prefix: /%sylius_admin.path_name%
# Required if you want NMI to tell your store what it did. Without it there is no endpoint and
# nothing arrives. No prefix: not the locale, not the admin path. See the README's "Webhooks".
jpm_martin_sylius_nmi_webhook:
resource: "@JpmMartinSyliusNmiPlugin/config/routes/webhook.yaml"
# Required if you turn saved cards on, and harmless if you do not. See the README's "Saved cards".
jpm_martin_sylius_nmi_shop_account:
resource: "@JpmMartinSyliusNmiPlugin/config/routes/shop_account.yaml"
prefix: /{_locale}/account
requirements:
_locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$
@@ -0,0 +1,20 @@
{
"bundles": {
"JpmMartin\\SyliusNmiPlugin\\JpmMartinSyliusNmiPlugin": ["all"]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
},
"add-lines": [
{
"file": "assets/shop/entrypoint.js",
"content": "import '@vendor/jpmmartin/sylius-nmi-plugin/assets/shop/entrypoint';",
"position": "bottom",
"warn_if_missing": true
}
],
"gitignore": [
"/config/encryption/*.key",
"!/config/encryption/test.key"
]
}
@@ -0,0 +1,14 @@
* <fg=blue>Four things no recipe can do, in this order:</>
<comment>yarn add @nmipayments/nmi-pay && yarn build</comment> the browser component and the shop build
<comment>bin/console doctrine:migrations:migrate</comment> the plugin's four tables
* <fg=blue>A key of your own, before the first payment method is saved.</> The skeleton's test.key is
published; point the store at a new path <comment>first</comment>, then generate — the generator writes
wherever the store points at that moment:
<comment>.env.local:</comment> SYLIUS_PAYMENT_ENCRYPTION_KEY_PATH=%kernel.project_dir%/config/encryption/payment.key
<comment>bin/console sylius:payment:generate-key</comment>
* <fg=blue>Then</> Configuration → Payment methods → Create → NMI, and read <comment>Testing against the sandbox</comment>
before the first payment: https://github.com/jpmmartin/SyliusNmiPlugin#readme
@@ -0,0 +1,2 @@
imports:
- { resource: "@OdiseoSyliusRbacPlugin/config/config.yaml" }
@@ -0,0 +1,3 @@
odiseo_sylius_rbac_admin:
resource: "@OdiseoSyliusRbacPlugin/config/routes/admin.yaml"
prefix: '/%sylius_admin.path_name%'
@@ -0,0 +1,8 @@
{
"bundles": {
"Odiseo\\SyliusRbacPlugin\\OdiseoSyliusRbacPlugin": ["all"]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
}
}
@@ -0,0 +1,10 @@
<bg=blue;fg=white> </>
<bg=blue;fg=white> What's next? </>
<bg=blue;fg=white> </>
* <fg=blue>Read</> the full installation guide at
<comment>https://github.com/odiseoteam/SyliusRbacPlugin/blob/master/doc/installation.md</>
* <fg=blue>Grant</> yourself access. A fresh install denies every administrator
everything, including the screen that assigns roles:
<comment>bin/console odiseo:rbac:grant <username-or-email> super_admin --create</>
@@ -0,0 +1,12 @@
# Default configuration for the tailsfadmin admin theme (Flex recipe).
# Adjust the menu to your application; `label` values are translation keys (i18n)
# or raw labels. See the bundle README.
tailsfadmin:
default_locale: fr
locales: ['fr', 'en', 'ar', 'es', 'de']
rtl_locales: ['ar']
menu:
-
group: menu.groups.menu
items:
- { label: menu.dashboard, path: /, icon: dashboard }
@@ -0,0 +1,12 @@
# AssetMapper path for the bundle's Stimulus controllers (Flex recipe).
#
# The bundle's prepend() does not survive the Flex config merge, so the controllers
# path (and the FullCalendar vendor-src shim) is declared here, on the host side.
# Kept in a SEPARATE file on purpose: Symfony merges framework.asset_mapper.paths
# from every config/packages/ file, so this adds to your asset_mapper.yaml
# without overwriting it.
framework:
asset_mapper:
paths:
'vendor/tailsfadmin/tailsfadmin-bundle/assets/controllers': 'bundles/tailsfadmin'
'vendor/tailsfadmin/tailsfadmin-bundle/assets/vendor-src': 'bundles/tailsfadmin-vendor'
@@ -0,0 +1,25 @@
{
"bundles": {
"Tailsfadmin\\TailsfadminBundle": ["all"]
},
"copy-from-recipe": {
"config/": "%CONFIG_DIR%/"
},
"post-install-output": [
"<bg=blue;fg=white> tailsfadmin </> admin theme installed.",
"",
" The bundle ships no CDN dependency — two steps for the assets:",
"",
" 1. Vendor the components' third-party JS libs (ApexCharts, flatpickr, Dropzone, …):",
" <comment>php bin/console tailsfadmin:assets:install</comment>",
"",
" 2. Import the theme into your Tailwind entrypoint (assets/styles/app.css):",
" <comment>@import \"tailwindcss\";</comment>",
" <comment>@import \"../../vendor/tailsfadmin/tailsfadmin-bundle/assets/styles/theme.css\";</comment>",
"",
" Then compile: <comment>php bin/console tailwind:build && php bin/console asset-map:compile</comment>",
"",
" The controllers' AssetMapper path is already set (config/packages/tailsfadmin_assets.yaml).",
" Documentation: <comment>https://github.com/thibmonier/tailsfadmin#readme</comment>"
]
}