Merge branch 'develop' into trunk
This commit is contained in:
commit
523715a3c1
7 changed files with 316 additions and 143 deletions
|
|
@ -47,3 +47,12 @@ LDC_WEB_CIDR_MANUAL_ALLOWED_LIST=
|
|||
# GITLAB API
|
||||
GITLAB_URL=
|
||||
GITLAB_TOKEN=
|
||||
|
||||
# SAML IDP
|
||||
## URL list separated by comma
|
||||
SAML_SP_URL_LIST=""
|
||||
## json sp config
|
||||
SAML_SP_CONFIG=''
|
||||
## IDP CERT
|
||||
SAMLIDP_KEY=
|
||||
SAMLIDP_CERT=
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
"require": {
|
||||
"php": "^8.2",
|
||||
"carlos-meneses/laravel-mpdf": "^2.1",
|
||||
"codegreencreative/laravel-samlidp": "^5.2",
|
||||
"diglactic/laravel-breadcrumbs": "^8.0",
|
||||
"doctrine/dbal": "^3.1",
|
||||
"graham-campbell/gitlab": "^7.0",
|
||||
|
|
@ -30,7 +31,6 @@
|
|||
"require-dev": {
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"kitloong/laravel-migrations-generator": "^6.8",
|
||||
"krlove/eloquent-model-generator": "dev-l10-compatibility",
|
||||
"laravel-lang/common": "^4.0",
|
||||
"laravel/pint": "^1.0",
|
||||
"laravel/sail": "^1.18",
|
||||
|
|
|
|||
255
composer.lock
generated
255
composer.lock
generated
|
|
@ -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": "ad318dcc6e3971dcae95e2b6c09d801f",
|
||||
"content-hash": "2ff0eab9fc2df8d36bf6220272d8074e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
|
@ -257,6 +257,60 @@
|
|||
],
|
||||
"time": "2023-12-20T15:40:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "codegreencreative/laravel-samlidp",
|
||||
"version": "v5.2.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/codegreencreative/laravel-samlidp.git",
|
||||
"reference": "c9cb84dcabe9178e5d5d429eeca198a17107c8c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/codegreencreative/laravel-samlidp/zipball/c9cb84dcabe9178e5d5d429eeca198a17107c8c7",
|
||||
"reference": "c9cb84dcabe9178e5d5d429eeca198a17107c8c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-zlib": "*",
|
||||
"illuminate/routing": "^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"illuminate/support": "^7.0|^8.0|^9.0|^10.0|^11.0",
|
||||
"litesaml/lightsaml": "^4.0",
|
||||
"php": "^7.2.5|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"CodeGreenCreative\\SamlIdp\\LaravelSamlIdpServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"CodeGreenCreative\\SamlIdp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Make your PHP Laravel application an Identification Provider using SAML 2.0. This package allows you to implement your own Identification Provider (idP) using the SAML 2.0 standard to be used with supporting SAML 2.0 Service Providers (SP).",
|
||||
"keywords": [
|
||||
"SAML 2.0",
|
||||
"SSO",
|
||||
"acl",
|
||||
"auth",
|
||||
"idp",
|
||||
"laravel",
|
||||
"saml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/codegreencreative/laravel-samlidp/issues",
|
||||
"source": "https://github.com/codegreencreative/laravel-samlidp/tree/v5.2.9"
|
||||
},
|
||||
"time": "2024-03-07T00:00:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v3.0.2",
|
||||
|
|
@ -3028,6 +3082,75 @@
|
|||
],
|
||||
"time": "2024-01-28T23:22:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "litesaml/lightsaml",
|
||||
"version": "v4.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/litesaml/lightsaml.git",
|
||||
"reference": "da88de24e699418918a128f0142dd09e2c41dd38"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/litesaml/lightsaml/zipball/da88de24e699418918a128f0142dd09e2c41dd38",
|
||||
"reference": "da88de24e699418918a128f0142dd09e2c41dd38",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.4",
|
||||
"psr/event-dispatcher": "^1.0",
|
||||
"robrichards/xmlseclibs": "~2.0|~3.0|~4.0",
|
||||
"symfony/http-foundation": "~5.0|~6.0|~7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"litesaml/schemas": "~1.0.0",
|
||||
"marcocesarato/php-conventional-changelog": "^1.15",
|
||||
"monolog/monolog": "^2.0|^3.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "~8.4|~9.5",
|
||||
"pimple/pimple": "~3.0",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"symfony/css-selector": "~5.0|~6.0|~7.0",
|
||||
"symfony/dom-crawler": "~5.0|~6.0|~7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LightSaml\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "William",
|
||||
"email": "work@suppo.fr"
|
||||
},
|
||||
{
|
||||
"name": "Milos Tomic",
|
||||
"email": "tmilos@gmail.com",
|
||||
"homepage": "https://github.com/tmilos/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "SAML 2.0 PHP library",
|
||||
"keywords": [
|
||||
"SAML 2.0",
|
||||
"Single Logout",
|
||||
"Single SignOn",
|
||||
"library",
|
||||
"lightSAML",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://docs.litesaml.com",
|
||||
"issues": "https://github.com/litesaml/lightsaml/issues",
|
||||
"source": "https://github.com/litesaml/lightsaml"
|
||||
},
|
||||
"time": "2024-02-08T11:59:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "m4tthumphrey/php-gitlab-api",
|
||||
"version": "11.13.0",
|
||||
|
|
@ -5497,6 +5620,48 @@
|
|||
],
|
||||
"time": "2024-04-27T21:32:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "robrichards/xmlseclibs",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/robrichards/xmlseclibs.git",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-openssl": "*",
|
||||
"php": ">= 5.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RobRichards\\XMLSecLibs\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "A PHP library for XML Security",
|
||||
"homepage": "https://github.com/robrichards/xmlseclibs",
|
||||
"keywords": [
|
||||
"security",
|
||||
"signature",
|
||||
"xml",
|
||||
"xmldsig"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/robrichards/xmlseclibs/issues",
|
||||
"source": "https://github.com/robrichards/xmlseclibs/tree/3.1.1"
|
||||
},
|
||||
"time": "2020-09-05T13:00:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sentry/sentry",
|
||||
"version": "4.7.0",
|
||||
|
|
@ -9424,90 +9589,6 @@
|
|||
],
|
||||
"time": "2024-02-06T14:42:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "krlove/code-generator",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/krlove/code-generator.git",
|
||||
"reference": "1ac521f5ef79a376282e3315ba6a13a83c63fb9a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/krlove/code-generator/zipball/1ac521f5ef79a376282e3315ba6a13a83c63fb9a",
|
||||
"reference": "1ac521f5ef79a376282e3315ba6a13a83c63fb9a",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Krlove\\CodeGenerator\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Code Generator",
|
||||
"support": {
|
||||
"issues": "https://github.com/krlove/code-generator/issues",
|
||||
"source": "https://github.com/krlove/code-generator/tree/1.0.1"
|
||||
},
|
||||
"time": "2022-02-20T12:24:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "krlove/eloquent-model-generator",
|
||||
"version": "dev-l10-compatibility",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel-shift/eloquent-model-generator.git",
|
||||
"reference": "d8f0280de04d85cf2991e5a5dd317f5dea239d95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel-shift/eloquent-model-generator/zipball/d8f0280de04d85cf2991e5a5dd317f5dea239d95",
|
||||
"reference": "d8f0280de04d85cf2991e5a5dd317f5dea239d95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/dbal": "^3.5",
|
||||
"illuminate/config": "^10.0",
|
||||
"illuminate/console": "^10.0",
|
||||
"illuminate/database": "^10.0",
|
||||
"illuminate/support": "^10.0",
|
||||
"krlove/code-generator": "^1.0",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5.10"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Krlove\\EloquentModelGenerator\\Provider\\GeneratorServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Krlove\\EloquentModelGenerator\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Krlove\\Tests\\Integration\\": "tests/integration"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Eloquent Model Generator",
|
||||
"support": {
|
||||
"source": "https://github.com/laravel-shift/eloquent-model-generator/tree/l10-compatibility"
|
||||
},
|
||||
"time": "2023-01-30T20:15:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel-lang/attributes",
|
||||
"version": "2.10.6",
|
||||
|
|
@ -12618,9 +12699,7 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"krlove/eloquent-model-generator": 20
|
||||
},
|
||||
"stability-flags": [],
|
||||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@ return [
|
|||
'throw' => false,
|
||||
],
|
||||
|
||||
'samlidp' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path() . '/samlidp',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
|||
74
config/samlidp.php
Normal file
74
config/samlidp.php
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
$saml_sp_list = explode(",", env('SAML_SP_URL_LIST', []));
|
||||
foreach ($saml_sp_list as $sp) {
|
||||
$sp_slo_redirects[$sp] = $sp;
|
||||
}
|
||||
|
||||
return [
|
||||
/**
|
||||
|--------------------------------------------------------------------------
|
||||
| SAML idP configuration file
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Use this file to configure the service providers you want to use.
|
||||
|
|
||||
*/
|
||||
// Outputs data to your laravel.log file for debugging.
|
||||
'debug' => (bool)env('APP_DEBUG', false),
|
||||
// Define the email address field name in the users table.
|
||||
'email_field' => 'email',
|
||||
// Define the name field in the users table.
|
||||
'name_field' => 'name',
|
||||
// The URI to your login page.
|
||||
'login_uri' => 'login',
|
||||
// Log out of the IdP after SLO.
|
||||
'logout_after_slo' => env('LOGOUT_AFTER_SLO', false),
|
||||
// The URI to the saml metadata file, this describes your idP.
|
||||
'issuer_uri' => 'saml/metadata',
|
||||
// The certificate.
|
||||
'cert' => env('SAMLIDP_CERT'),
|
||||
// Name of the certificate PEM file, ignored if cert is used.
|
||||
'certname' => 'cert.pem',
|
||||
// The certificate key.
|
||||
'key' => env('SAMLIDP_KEY'),
|
||||
// Name of the certificate key PEM file, ignored if key is used.
|
||||
'keyname' => 'key.pem',
|
||||
// Encrypt requests and responses.
|
||||
'encrypt_assertion' => true,
|
||||
// Make sure messages are signed.
|
||||
'messages_signed' => true,
|
||||
// Defind what digital algorithm you want to use.
|
||||
'digest_algorithm' => \RobRichards\XMLSecLibs\XMLSecurityDSig::SHA256,
|
||||
// List of all service providers.
|
||||
// 'sp' => [
|
||||
// Base64 encoded ACS URL
|
||||
// 'aHR0cHM6Ly9teWZhY2Vib29rd29ya3BsYWNlLmZhY2Vib29rLmNvbS93b3JrL3NhbWwucGhw' => [
|
||||
// Your destination is the ACS URL of the Service Provider
|
||||
// 'destination' => 'https://myfacebookworkplace.facebook.com/work/saml.php',
|
||||
// 'logout' => 'https://myfacebookworkplace.facebook.com/work/sls.php',
|
||||
// SP certificate
|
||||
// 'certificate' => '',
|
||||
// Turn off auto appending of the idp query param
|
||||
// 'query_params' => false,
|
||||
// Turn off the encryption of the assertion per SP
|
||||
// 'encrypt_assertion' => false
|
||||
// ].
|
||||
// ],.
|
||||
'sp' => json_decode(env('SAML_SP_CONFIG', "{}"), true),
|
||||
|
||||
// If you need to redirect after SLO depending on SLO initiator
|
||||
// Key is beginning of HTTP_REFERER value from SERVER, value is redirect path.
|
||||
'sp_slo_redirects' => $sp_slo_redirects,
|
||||
|
||||
// All of the Laravel SAML IdP event / listener mappings.
|
||||
'events' => [
|
||||
'CodeGreenCreative\SamlIdp\Events\Assertion' => [],
|
||||
'Illuminate\Auth\Events\Logout' => ['CodeGreenCreative\SamlIdp\Listeners\SamlLogout'],
|
||||
'Illuminate\Auth\Events\Authenticated' => ['CodeGreenCreative\SamlIdp\Listeners\SamlAuthenticated'],
|
||||
'Illuminate\Auth\Events\Login' => ['CodeGreenCreative\SamlIdp\Listeners\SamlLogin'],
|
||||
],
|
||||
|
||||
// List of guards saml idp will catch Authenticated, Login and Logout events.
|
||||
'guards' => ['backend'],
|
||||
];
|
||||
|
|
@ -25,6 +25,10 @@ data:
|
|||
SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}"
|
||||
GITLAB_URL: "https://${CI_SERVER_HOST}"
|
||||
GITLAB_TOKEN: "${APP_GITLAB_TOKEN}"
|
||||
SAMLIDP_KEY: "${APP_SAMLIDP_KEY}"
|
||||
SAMLIDP_CERT: "${APP_SAMLIDP_CERT}"
|
||||
SAML_SP_URL_LIST: "${APP_SAML_SP_URL_LIST}"
|
||||
SAML_SP_CONFIG: "${APP_SAML_SP_CONFIG}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
|
|
|||
|
|
@ -4,65 +4,67 @@
|
|||
@section('description', __('Formulaire d\'authentification au back-office.'))
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8 p-0">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Connexion') }}</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
<div class="row mb-3">
|
||||
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Adresse Email') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email"
|
||||
value="{{ old('email') }}" autocomplete="email" autofocus required>
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Mot de passe') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror"
|
||||
name="password" autocomplete="current-password" required>
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check p-0">
|
||||
<input class="form-check-input mx-0" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }} role="button">
|
||||
<label class="form-check-label user-select-none ps-2" for="remember" role="button">
|
||||
{{ __('Se souvenir de moi') }}
|
||||
</label>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8 p-0">
|
||||
<div class="card">
|
||||
<div class="card-header">{{ __('Connexion') }}</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ route('login') }}">
|
||||
@csrf
|
||||
@samlidp
|
||||
<div class="row mb-3">
|
||||
<label class="col-md-4 col-form-label text-md-end" for="email">{{ __('Adresse Email') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control @error('email') is-invalid @enderror" id="email" name="email"
|
||||
type="email" value="{{ old('email') }}" autocomplete="email" autofocus required>
|
||||
@error('email')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<span>{{ __('Connexion') }}</span>
|
||||
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||
</button>
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn btn-link text-decoration-none" href="{{ route('password.request') }}">
|
||||
{{ __('Mot de passe oublié ?') }}
|
||||
</a>
|
||||
@endif
|
||||
<div class="row mb-3">
|
||||
<label class="col-md-4 col-form-label text-md-end" for="password">{{ __('Mot de passe') }}</label>
|
||||
<div class="col-md-6">
|
||||
<input class="form-control @error('password') is-invalid @enderror" id="password" name="password"
|
||||
type="password" autocomplete="current-password" required>
|
||||
@error('password')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
<strong>{{ $message }}</strong>
|
||||
</span>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6 offset-md-4">
|
||||
<div class="form-check p-0">
|
||||
<input class="form-check-input mx-0" id="remember" name="remember" type="checkbox" role="button"
|
||||
{{ old('remember') ? 'checked' : '' }}>
|
||||
<label class="form-check-label user-select-none ps-2" for="remember" role="button">
|
||||
{{ __('Se souvenir de moi') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-0">
|
||||
<div class="col-md-8 offset-md-4">
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<span>{{ __('Connexion') }}</span>
|
||||
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
||||
</button>
|
||||
@if (Route::has('password.request'))
|
||||
<a class="btn btn-link text-decoration-none" href="{{ route('password.request') }}">
|
||||
{{ __('Mot de passe oublié ?') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue