Merge branch 'issue-153' into 'le-gaulois-2024'

feat: add admin secure

See merge request ldc-web/projets/le-gaulois!106
This commit is contained in:
Vincent BRIDIER 2024-09-04 09:25:55 +00:00
commit 39412059f1
6 changed files with 466 additions and 114 deletions

View file

@ -68,3 +68,11 @@ CRM_PASSWORD=
# DIGITAL RECRUITER
DIGITAL_RECRUITER_URL=
# ADMIN SECURE
# - API ENDPOINT (Optional)
LDC_WEB_API_ENDPOINT="https://ldc-web.ldc.fr/api/ldc-networks"
# - API KEY
LDC_WEB_API_KEY=""
# - LIST SEPARATED WITH ',' (Optional)
LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=""

View file

@ -14,3 +14,10 @@ apt install trimage
### TODO
FIXME: supprimer le dossier resources/assets/images/tmp
# Copy paste from the admin secure readme.md
Put every min in PROD :
php artisan schedule:run

1
composer.json Executable file → Normal file
View file

@ -27,6 +27,7 @@
"moneyphp/money": "^4.5",
"sentry/sentry-laravel": "*",
"snipe/banbuilder": "^2.3",
"uwil/admin-secure-laravel": "^3.0",
"uwil/k8s-laravel": "^1.4",
"uwil/seo-laravel": "^3.0"
},

275
composer.lock generated Executable file → Normal file
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "17cdf7bfd5deae9afebabeb21cad3468",
"content-hash": "6d9d4cc3c2c0ea4e689cb7cf89c65562",
"packages": [
{
"name": "brick/math",
@ -566,6 +566,102 @@
],
"time": "2023-08-10T19:36:49+00:00"
},
{
"name": "dxw/cidr",
"version": "v3.2.0",
"source": {
"type": "git",
"url": "https://github.com/dxw/cidr.git",
"reference": "b07dd398f5a93441f57a687982bc7d0ffb96729a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dxw/cidr/zipball/b07dd398f5a93441f57a687982bc7d0ffb96729a",
"reference": "b07dd398f5a93441f57a687982bc7d0ffb96729a",
"shasum": ""
},
"require": {
"dxw/result": "^1.0",
"php": "^7.4||^8.1",
"phpseclib/phpseclib": "^2.0"
},
"require-dev": {
"dxw/php-cs-fixer-config": "^2.0",
"kahlan/kahlan": "^5.2",
"vimeo/psalm": "^5.14"
},
"type": "library",
"autoload": {
"psr-4": {
"Dxw\\CIDR\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "dxw",
"email": "team@govpress.com",
"homepage": "https://www.dxw.com"
}
],
"description": "IP address matching with CIDR ranges",
"homepage": "https://github.com/dxw/cidr",
"support": {
"issues": "https://github.com/dxw/cidr/issues",
"source": "https://github.com/dxw/cidr/tree/v3.2.0"
},
"time": "2023-08-14T10:14:13+00:00"
},
{
"name": "dxw/result",
"version": "v1.0.6",
"source": {
"type": "git",
"url": "https://github.com/dxw/result.git",
"reference": "d554bb10f0cf74056ccd26526688e194652eef79"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dxw/result/zipball/d554bb10f0cf74056ccd26526688e194652eef79",
"reference": "d554bb10f0cf74056ccd26526688e194652eef79",
"shasum": ""
},
"require": {
"php": "^7.4||^8.1"
},
"require-dev": {
"dxw/php-cs-fixer-config": "^2.1",
"kahlan/kahlan": "^5.2",
"vimeo/psalm": "^4"
},
"type": "library",
"autoload": {
"psr-4": {
"Dxw\\Result\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mallory Adams",
"email": "mallory@dxw.com",
"homepage": "https://www.dxw.com/"
}
],
"description": "Result values",
"homepage": "https://github.com/dxw/result",
"support": {
"issues": "https://github.com/dxw/result/issues",
"source": "https://github.com/dxw/result/tree/v1.0.6"
},
"time": "2023-07-19T11:14:28+00:00"
},
{
"name": "egulias/email-validator",
"version": "4.0.2",
@ -3634,6 +3730,116 @@
],
"time": "2024-07-20T21:41:07+00:00"
},
{
"name": "phpseclib/phpseclib",
"version": "2.0.47",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "b7d7d90ee7df7f33a664b4aea32d50a305d35adb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/b7d7d90ee7df7f33a664b4aea32d50a305d35adb",
"reference": "b7d7d90ee7df7f33a664b4aea32d50a305d35adb",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"phing/phing": "~2.7",
"phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
"squizlabs/php_codesniffer": "~2.0"
},
"suggest": {
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
"ext-xml": "Install the XML extension to load XML formatted public keys."
},
"type": "library",
"autoload": {
"files": [
"phpseclib/bootstrap.php"
],
"psr-4": {
"phpseclib\\": "phpseclib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jim Wigginton",
"email": "terrafrost@php.net",
"role": "Lead Developer"
},
{
"name": "Patrick Monnerat",
"email": "pm@datasphere.ch",
"role": "Developer"
},
{
"name": "Andreas Fischer",
"email": "bantu@phpbb.com",
"role": "Developer"
},
{
"name": "Hans-Jürgen Petrich",
"email": "petrich@tronic-media.com",
"role": "Developer"
},
{
"name": "Graham Campbell",
"email": "graham@alt-three.com",
"role": "Developer"
}
],
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
"homepage": "http://phpseclib.sourceforge.net",
"keywords": [
"BigInteger",
"aes",
"asn.1",
"asn1",
"blowfish",
"crypto",
"cryptography",
"encryption",
"rsa",
"security",
"sftp",
"signature",
"signing",
"ssh",
"twofish",
"x.509",
"x509"
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/2.0.47"
},
"funding": [
{
"url": "https://github.com/terrafrost",
"type": "github"
},
{
"url": "https://www.patreon.com/phpseclib",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
"type": "tidelift"
}
],
"time": "2024-02-26T04:55:38+00:00"
},
{
"name": "psr/clock",
"version": "1.0.0",
@ -7277,6 +7483,73 @@
},
"time": "2023-12-08T13:03:43+00:00"
},
{
"name": "uwil/admin-secure-laravel",
"version": "3.0.0",
"source": {
"type": "git",
"url": "git@lab.s-web.fr:ldc-web/projets/ldc-web-admin-secure-laravel.git",
"reference": "6bf17bd7a45b2bdc3a86cef381a86e77bc339469"
},
"dist": {
"type": "zip",
"url": "https://lab.s-web.fr/api/v4/projects/20/packages/composer/archives/uwil/admin-secure-laravel.zip?sha=6bf17bd7a45b2bdc3a86cef381a86e77bc339469",
"reference": "6bf17bd7a45b2bdc3a86cef381a86e77bc339469",
"shasum": ""
},
"require": {
"dxw/cidr": "^3.2",
"illuminate/support": "~11",
"laravel/framework": "~11",
"php": "^8.3",
"symfony/options-resolver": "^7.0"
},
"require-dev": {
"larastan/larastan": "^2.9",
"orchestra/testbench": "^9",
"phpunit/php-code-coverage": "^11",
"phpunit/phpunit": "^11",
"slevomat/coding-standard": "^8",
"squizlabs/php_codesniffer": "^3"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Uwil\\AdminSecure\\Laravel\\AdminSecureServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Uwil\\AdminSecure\\Laravel\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Uwil\\AdminSecure\\Laravel\\Tests\\": "tests"
}
},
"scripts": {
"test": [
"vendor/bin/phpunit"
],
"post-autoload-dump": [
"@php ./vendor/bin/testbench package:discover --ansi"
]
},
"license": [
"MIT"
],
"authors": [
{
"name": "Equipe Web",
"email": "equipe.web@ldc.fr",
"homepage": "https://www.ldc.fr"
}
],
"description": "Restrict access to LDC Network"
},
{
"name": "uwil/k8s-laravel",
"version": "1.4.0",

View file

@ -23,6 +23,7 @@ data:
MATOMO_SITE_ID: "${APP_MATOMO_SITE_ID}"
SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}"
DIGITAL_RECRUITER_URL: "${APP_DIGITAL_RECRUITER_URL}"
LDC_WEB_API_KEY: "${APP_LDC_WEB_API_KEY}"
---
apiVersion: v1
@ -32,7 +33,7 @@ metadata:
spec:
storageClassName: "csi-cinder-classic"
accessModes:
- ReadWriteOnce
- ReadWriteOnce
resources:
requests:
storage: $APP_PVC_SIZE
@ -53,25 +54,25 @@ spec:
app: ${CI_PROJECT_PATH_SLUG}-app
spec:
containers:
- name: ${CI_PROJECT_PATH_SLUG}-container
image: $IMAGE_TAG
envFrom:
- configMapRef:
name: ${CI_PROJECT_PATH_SLUG}-config-map
volumeMounts:
- name: storage
mountPath: /app/srcs/storage
- name: ${CI_PROJECT_PATH_SLUG}-container
image: $IMAGE_TAG
envFrom:
- configMapRef:
name: ${CI_PROJECT_PATH_SLUG}-config-map
volumeMounts:
- name: storage
mountPath: /app/srcs/storage
imagePullSecrets:
- name: docker-registry-credentials
- name: docker-registry-credentials
securityContext:
runAsUser: 33
runAsGroup: 33
fsGroup: 33
fsGroupChangePolicy: "OnRootMismatch"
volumes:
- name: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
- name: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
---
apiVersion: v1
@ -82,8 +83,8 @@ spec:
selector:
app: ${CI_PROJECT_PATH_SLUG}-app
ports:
- port: 80
targetPort: 443
- port: 80
targetPort: 443
---
apiVersion: traefik.io/v1alpha1
@ -92,16 +93,16 @@ metadata:
name: ${CI_PROJECT_PATH_SLUG}-ingress-route
spec:
entryPoints:
- web
- websecure
- web
- websecure
routes:
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
kind: Rule
services:
- name: ${CI_PROJECT_PATH_SLUG}-service
port: 80
middlewares:
- name: redirect-no-www-to-www
- match: Host(`${APP_DOMAIN}`) || Host(`www.${APP_DOMAIN}`)
kind: Rule
services:
- name: ${CI_PROJECT_PATH_SLUG}-service
port: 80
middlewares:
- name: redirect-no-www-to-www
tls:
secretName: ${CRT_TLS_NAME}
@ -119,35 +120,35 @@ spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- ${CI_PROJECT_PATH_SLUG}-app
topologyKey: "kubernetes.io/hostname"
namespaces: [$KUBE_NAMESPACE]
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- ${CI_PROJECT_PATH_SLUG}-app
topologyKey: "kubernetes.io/hostname"
namespaces: [$KUBE_NAMESPACE]
containers:
- name: ${CI_PROJECT_PATH_SLUG}-scheduled
image: $IMAGE_TAG
imagePullPolicy: IfNotPresent
command:
- "php"
args:
- "artisan"
- "schedule:run"
envFrom:
- configMapRef:
name: ${CI_PROJECT_PATH_SLUG}-config-map
volumeMounts:
- name: storage
mountPath: /app/srcs/storage
- name: ${CI_PROJECT_PATH_SLUG}-scheduled
image: $IMAGE_TAG
imagePullPolicy: IfNotPresent
command:
- "php"
args:
- "artisan"
- "schedule:run"
envFrom:
- configMapRef:
name: ${CI_PROJECT_PATH_SLUG}-config-map
volumeMounts:
- name: storage
mountPath: /app/srcs/storage
imagePullSecrets:
- name: docker-registry-credentials
- name: docker-registry-credentials
volumes:
- name: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
- name: storage
persistentVolumeClaim:
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
securityContext:
runAsUser: 33
runAsGroup: 33

View file

@ -30,7 +30,7 @@ use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function () {
Route::middleware(['throttle:web', 'admin-secure'])->prefix('bo')->name('bo.')->group(function () {
// * Authenticable routes
Route::namespace('\App\Http\Controllers\Bo')
->group(function () {
@ -51,10 +51,12 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
// * USERS.
Route::resource('users', UserController::class);
Route::patch('/users/{user}/change-published', [
UserController::class, 'changePublished'
UserController::class,
'changePublished'
])->name('users.change-published');
Route::get('/users/{user}/duplicate', [
UserController::class, 'duplicate'
UserController::class,
'duplicate'
])->name('users.duplicate');
// * GENERAL SETTINGS
@ -87,34 +89,42 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
// * PROFESSIONS.
Route::resource('professions', ProfessionController::class);
Route::patch('/professions/{profession}/change-published', [
ProfessionController::class, 'changePublished'
ProfessionController::class,
'changePublished'
])->name('professions.change-published');
Route::get('/professions/{profession}/duplicate', [
ProfessionController::class, 'duplicate'
ProfessionController::class,
'duplicate'
])->name('professions.duplicate');
// * KEYNUMBERS.
Route::resource('key_numbers', KeyNumberController::class);
Route::patch('/key_numbers/{key_number}/change-published', [
KeyNumberController::class, 'changePublished'
KeyNumberController::class,
'changePublished'
])->name('key_numbers.change-published');
Route::patch('/key_numbers/{key_number}/change-order/{direction}', [
KeyNumberController::class, 'changeOrder'
KeyNumberController::class,
'changeOrder'
])->where('direction', 'up|down')->name('key_numbers.change-order');
Route::get('/key_numbers/{key_number}/duplicate', [
KeyNumberController::class, 'duplicate'
KeyNumberController::class,
'duplicate'
])->name('key_numbers.duplicate');
// * BRAND_ADVANTAGES.
Route::resource('brand_advantages', BrandAdvantageController::class);
Route::patch('/brand_advantages/{brand_advantage}/change-order/{direction}', [
BrandAdvantageController::class, 'changeOrder'
BrandAdvantageController::class,
'changeOrder'
])->where('direction', 'up|down')->name('brand_advantages.change-order');
Route::patch('/brand_advantages/{brand_advantage}/change-published', [
BrandAdvantageController::class, 'changePublished'
BrandAdvantageController::class,
'changePublished'
])->name('brand_advantages.change-published');
Route::get('/brand_advantages/{brand_advantage}/duplicate', [
BrandAdvantageController::class, 'duplicate'
BrandAdvantageController::class,
'duplicate'
])->name('brand_advantages.duplicate');
// * DEMARCHE_SLIDES.
@ -122,13 +132,16 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:text');
Route::patch('/demarche_slides/{demarche_slide}/change-order/{direction}', [
DemarcheSlideController::class, 'changeOrder'
DemarcheSlideController::class,
'changeOrder'
])->where('direction', 'up|down')->name('demarche_slides.change-order');
Route::patch('/demarche_slides/{demarche_slide}/change-published', [
DemarcheSlideController::class, 'changePublished'
DemarcheSlideController::class,
'changePublished'
])->name('demarche_slides.change-published');
Route::get('/demarche_slides/{demarche_slide}/duplicate', [
DemarcheSlideController::class, 'duplicate'
DemarcheSlideController::class,
'duplicate'
])->name('demarche_slides.duplicate');
// * MAIN_SLIDES.
@ -136,13 +149,16 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:text');
Route::patch('/main_slides/{main_slide}/change-order/{direction}', [
MainSlideController::class, 'changeOrder'
MainSlideController::class,
'changeOrder'
])->where('direction', 'up|down')->name('main_slides.change-order');
Route::patch('/main_slides/{main_slide}/change-published', [
MainSlideController::class, 'changePublished'
MainSlideController::class,
'changePublished'
])->name('main_slides.change-published');
Route::get('/main_slides/{main_slide}/duplicate', [
MainSlideController::class, 'duplicate'
MainSlideController::class,
'duplicate'
])->name('main_slides.duplicate');
// * RANGES.
@ -150,20 +166,25 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description');
Route::patch('/ranges/{range}/change-order/{direction}', [
RangeController::class, 'changeOrder'
RangeController::class,
'changeOrder'
])->where('direction', 'up|down')->name('ranges.change-order');
Route::patch('/ranges/{range}/change-published', [
RangeController::class, 'changePublished'
RangeController::class,
'changePublished'
])->name('ranges.change-published');
Route::get('/ranges/{range}/duplicate', [
RangeController::class, 'duplicate'
RangeController::class,
'duplicate'
])->name('ranges.duplicate');
// Change order of ranges.
Route::get('/ranges/{range}/change-subranges-order', [
RangeController::class, 'editSubrangesOrder'
RangeController::class,
'editSubrangesOrder'
])->name('ranges.edit-subranges-order');
Route::patch('/ranges/{range}/update-subranges-order', [
RangeController::class, 'updateSubrangesOrder'
RangeController::class,
'updateSubrangesOrder'
])->name('ranges.update-subranges-order');
Route::get('/ranges/json/paginate', [RangeController::class, 'jsonPaginateModels'])
->name('ranges.json-paginate');
@ -173,10 +194,12 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description');
Route::patch('/subranges/{subrange}/change-published', [
SubrangeController::class, 'changePublished'
SubrangeController::class,
'changePublished'
])->name('subranges.change-published');
Route::get('/subranges/{subrange}/duplicate', [
SubrangeController::class, 'duplicate'
SubrangeController::class,
'duplicate'
])->name('subranges.duplicate');
Route::get('/subranges/json/paginate', [SubrangeController::class, 'jsonPaginateModels'])
->name('subranges.json-paginate');
@ -186,20 +209,25 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description');
Route::patch('/meats/{meat}/change-order/{direction}', [
MeatController::class, 'changeOrder'
MeatController::class,
'changeOrder'
])->where('direction', 'up|down')->name('meats.change-order');
Route::patch('/meats/{meat}/change-published', [
MeatController::class, 'changePublished'
MeatController::class,
'changePublished'
])->name('meats.change-published');
Route::get('/meats/{meat}/duplicate', [
MeatController::class, 'duplicate'
MeatController::class,
'duplicate'
])->name('meats.duplicate');
// Change order of submodels.
Route::get('/meats/{meat}/change-submeats-order', [
MeatController::class, 'editSubmeatsOrder'
MeatController::class,
'editSubmeatsOrder'
])->name('meats.edit-submeats-order');
Route::patch('/meats/{meat}/update-submeats-order', [
MeatController::class, 'updateSubmeatsOrder'
MeatController::class,
'updateSubmeatsOrder'
])->name('meats.update-submeats-order');
Route::get('/meats/json/paginate', [MeatController::class, 'jsonPaginateModels'])
->name('meats.json-paginate');
@ -209,10 +237,12 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description');
Route::patch('/submeats/{submeat}/change-published', [
SubmeatController::class, 'changePublished'
SubmeatController::class,
'changePublished'
])->name('submeats.change-published');
Route::get('/submeats/{submeat}/duplicate', [
SubmeatController::class, 'duplicate'
SubmeatController::class,
'duplicate'
])->name('submeats.duplicate');
Route::get('/submeats/json/paginate', [SubmeatController::class, 'jsonPaginateModels'])
->name('submeats.json-paginate');
@ -222,13 +252,16 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description');
Route::patch('/product_types/{product_type}/change-published', [
ProductTypeController::class, 'changePublished'
ProductTypeController::class,
'changePublished'
])->name('product_types.change-published');
Route::patch('/product_types/{product_type}/change-button-status', [
ProductTypeController::class, 'changeButtonStatus'
ProductTypeController::class,
'changeButtonStatus'
])->name('product_types.change-button-status');
Route::get('/product_types/{product_type}/duplicate', [
ProductTypeController::class, 'duplicate'
ProductTypeController::class,
'duplicate'
])->name('product_types.duplicate');
Route::get('/product-types/json/paginate', [ProductTypeController::class, 'jsonPaginateModels'])
->name('product_types.json-paginate');
@ -236,36 +269,45 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
// * CLAIMS.
Route::resource('claims', ClaimController::class);
Route::patch('/claims/{claim}/change-published', [
ClaimController::class, 'changePublished'
ClaimController::class,
'changePublished'
])->name('claims.change-published');
Route::get('/claims/{claim}/duplicate', [
ClaimController::class, 'duplicate'
ClaimController::class,
'duplicate'
])->name('claims.duplicate');
Route::get('/claims/json/paginate', [ClaimController::class, 'jsonPaginateModels'])
->name('claims.json-paginate');
// * APPROACHES.
Route::get('/approaches/{approach_type}', [
ApproachController::class, 'index'
ApproachController::class,
'index'
])->name('approaches.index');
Route::get('/approaches/{approach_type}/create', [
ApproachController::class, 'create'
ApproachController::class,
'create'
])->name('approaches.create');
Route::post('/approaches/{approach_type}/store', [
ApproachController::class, 'store'
ApproachController::class,
'store'
])->name('approaches.store');
Route::get('/approaches/{approach}/show', [
ApproachController::class, 'show'
ApproachController::class,
'show'
])->name('approaches.show');
Route::resource('approaches', ApproachController::class)->only(['edit', 'update', 'destroy']);
Route::patch('/approaches/{approach}/change-order/{direction}', [
ApproachController::class, 'changeOrder'
ApproachController::class,
'changeOrder'
])->where('direction', 'up|down')->name('approaches.change-order');
Route::patch('/approaches/{approach}/change-published', [
ApproachController::class, 'changePublished'
ApproachController::class,
'changePublished'
])->name('approaches.change-published');
Route::get('/approaches/{approach}/duplicate', [
ApproachController::class, 'duplicate'
ApproachController::class,
'duplicate'
])->name('approaches.duplicate');
Route::get('/approaches/json/paginate', [ApproachController::class, 'jsonPaginateDemarches'])
->name('approaches.json-paginate');
@ -273,22 +315,27 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
// * CONSUMPTION MOMENT.
Route::resource('consumption_moments', ConsumptionMomentController::class);
Route::get('/consumption_moments/{consumption_moment}/duplicate', [
ConsumptionMomentController::class, 'duplicate'
ConsumptionMomentController::class,
'duplicate'
])->name('consumption_moments.duplicate');
// * VIDEOS.
Route::resource('videos', VideoController::class);
Route::patch('/videos/{video}/change-published', [
VideoController::class, 'changePublished'
VideoController::class,
'changePublished'
])->name('videos.change-published');
Route::patch('/videos/{video}/change-homepage', [
VideoController::class, 'changeHomepage'
VideoController::class,
'changeHomepage'
])->name('videos.change-homepage');
Route::patch('/videos/{video}/change-order/{direction}', [
VideoController::class, 'changeOrder'
VideoController::class,
'changeOrder'
])->where('direction', 'up|down')->name('videos.change-order');
Route::get('/videos/{video}/duplicate', [
VideoController::class, 'duplicate'
VideoController::class,
'duplicate'
])->name('videos.duplicate');
Route::get('/videos/json/paginate', [VideoController::class, 'jsonPaginateModels'])
->name('videos.json-paginate');
@ -298,13 +345,16 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:preparation,advice');
Route::get('/recipes/{recipe}/duplicate', [
RecipeController::class, 'duplicate'
RecipeController::class,
'duplicate'
])->name('recipes.duplicate');
Route::patch('/recipes/{recipe}/change-published', [
RecipeController::class, 'changePublished'
RecipeController::class,
'changePublished'
])->name('recipes.change-published');
Route::patch('/recipes/{recipe}/change-highlight', [
RecipeController::class, 'changeHighlight'
RecipeController::class,
'changeHighlight'
])->name('recipes.change-highlight');
Route::get('/recipes/json/paginate', [ConsumptionMomentController::class, 'jsonPaginateModels'])
->name('recipes.json-paginate');
@ -316,10 +366,12 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description,details,preparation,ingredients');
Route::get('/products/{product}/duplicate', [
ProductController::class, 'duplicate'
ProductController::class,
'duplicate'
])->name('products.duplicate');
Route::patch('/products/{product}/change-published', [
ProductController::class, 'changePublished'
ProductController::class,
'changePublished'
])->name('products.change-published');
Route::get('/products/json/paginate', [ProductController::class, 'jsonPaginateModels'])
->name('products.json-paginate');
@ -327,25 +379,31 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
// * OFFERS.
Route::resource('offers', OfferController::class);
Route::patch('/offers/{offer}/change-published', [
OfferController::class, 'changePublished'
OfferController::class,
'changePublished'
])->name('offers.change-published');
Route::patch('/offers/{offer}/change-order/{direction}', [
OfferController::class, 'changeOrder'
OfferController::class,
'changeOrder'
])->where('direction', 'up|down')->name('offers.change-order');
Route::get('/offers/{offer}/duplicate', [
OfferController::class, 'duplicate'
OfferController::class,
'duplicate'
])->name('offers.duplicate');
// * TESTIMONIALS.
Route::resource('testimonials', TestimonialController::class);
Route::patch('/testimonials/{testimonial}/change-published', [
TestimonialController::class, 'changePublished'
TestimonialController::class,
'changePublished'
])->name('testimonials.change-published');
Route::patch('/testimonials/{testimonial}/change-order/{direction}', [
TestimonialController::class, 'changeOrder'
TestimonialController::class,
'changeOrder'
])->where('direction', 'up|down')->name('testimonials.change-order');
Route::get('/testimonials/{testimonial}/duplicate', [
TestimonialController::class, 'duplicate'
TestimonialController::class,
'duplicate'
])->name('testimonials.duplicate');
// * HISTORICAL MILESTONES.
@ -353,19 +411,23 @@ Route::middleware(['throttle:web'])->prefix('bo')->name('bo.')->group(function (
->withoutMiddleware('htmlsanitize')
->middleware('htmlsanitize:description');
Route::get('/historical_milestones/{historical_milestone}/duplicate', [
HistoricalMilestoneController::class, 'duplicate'
HistoricalMilestoneController::class,
'duplicate'
])->name('historical_milestones.duplicate');
Route::patch('/historical_milestones/{historical_milestone}/change-published', [
HistoricalMilestoneController::class, 'changePublished'
HistoricalMilestoneController::class,
'changePublished'
])->name('historical_milestones.change-published');
// * NEWS CORPORATE.
Route::resource('news_corporates', NewsCorporateController::class);
Route::patch('/news_corporates/{news_corporate}/change-published', [
NewsCorporateController::class, 'changePublished'
NewsCorporateController::class,
'changePublished'
])->name('news_corporates.change-published');
Route::get('/news_corporates/{news_corporate}/duplicate', [
NewsCorporateController::class, 'duplicate'
NewsCorporateController::class,
'duplicate'
])->name('news_corporates.duplicate');
Route::middleware('can:isConceptor')->group(function () {