feat: scramble

This commit is contained in:
leon-morival 2025-11-28 14:56:42 +01:00
parent e84860f925
commit e165cd7e28
14 changed files with 693 additions and 122 deletions

View File

@ -4,7 +4,7 @@ APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_LOCALE=en
APP_LOCALE=fr
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US

View File

@ -5,8 +5,10 @@ namespace App\Http\Controllers;
use App\Http\Requests\Auth\LoginRequest;
use App\Http\Requests\Auth\RegisterRequest;
use App\Models\User;
use Hash;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\Response;
class AuthController extends Controller
@ -70,15 +72,6 @@ class AuthController extends Controller
}
/**
* Determine the token name to use for the access token.
*

View File

@ -2,7 +2,12 @@
namespace App\Providers;
use Dedoc\Scramble\Scramble;
use Dedoc\Scramble\Support\Generator\OpenApi;
use Dedoc\Scramble\Support\Generator\SecurityScheme;
use Illuminate\Routing\Route;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
class AppServiceProvider extends ServiceProvider
{
@ -19,6 +24,14 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
//
Scramble::configure()
->routes(function (Route $route) {
return Str::startsWith($route->uri, 'api/');
})
->withDocumentTransformers(function (OpenApi $openApi) {
$openApi->secure(
SecurityScheme::http('bearer')
);
});
}
}

View File

@ -6,7 +6,7 @@ use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
// web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',

View File

@ -10,6 +10,7 @@
"license": "MIT",
"require": {
"php": "^8.2",
"dedoc/scramble": "^0.13.5",
"laravel/framework": "^12.0",
"laravel/sanctum": "^4.0",
"laravel/tinker": "^2.10.1"

357
composer.lock generated
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": "1ef9e2b78ee122ba1af242cab0df7034",
"content-hash": "df51c00372eede5c1382e8cb8bc2a796",
"packages": [
{
"name": "brick/math",
@ -135,6 +135,86 @@
],
"time": "2024-02-09T16:56:22+00:00"
},
{
"name": "dedoc/scramble",
"version": "v0.13.5",
"source": {
"type": "git",
"url": "https://github.com/dedoc/scramble.git",
"reference": "b827b5f96fb9f0f6069af65faeefdde9fedf4b9e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dedoc/scramble/zipball/b827b5f96fb9f0f6069af65faeefdde9fedf4b9e",
"reference": "b827b5f96fb9f0f6069af65faeefdde9fedf4b9e",
"shasum": ""
},
"require": {
"illuminate/contracts": "^10.0|^11.0|^12.0",
"myclabs/deep-copy": "^1.12",
"nikic/php-parser": "^5.0",
"php": "^8.1",
"phpstan/phpdoc-parser": "^1.0|^2.0",
"spatie/laravel-package-tools": "^1.9.2"
},
"require-dev": {
"larastan/larastan": "^3.3",
"laravel/pint": "^v1.1.0",
"nunomaduro/collision": "^7.0|^8.0",
"orchestra/testbench": "^8.0|^9.0|^10.0",
"pestphp/pest": "^2.34|^3.7",
"pestphp/pest-plugin-laravel": "^2.3|^3.1",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^10.5|^11.5.3",
"spatie/laravel-permission": "^6.10",
"spatie/pest-plugin-snapshots": "^2.1"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Dedoc\\Scramble\\ScrambleServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Dedoc\\Scramble\\": "src",
"Dedoc\\Scramble\\Database\\Factories\\": "database/factories"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Lytvynenko",
"email": "litvinenko95@gmail.com",
"role": "Developer"
}
],
"description": "Automatic generation of API documentation for Laravel applications.",
"homepage": "https://github.com/dedoc/scramble",
"keywords": [
"documentation",
"laravel",
"openapi"
],
"support": {
"issues": "https://github.com/dedoc/scramble/issues",
"source": "https://github.com/dedoc/scramble/tree/v0.13.5"
},
"funding": [
{
"url": "https://github.com/romalytvynenko",
"type": "github"
}
],
"time": "2025-11-24T09:09:10+00:00"
},
{
"name": "dflydev/dot-access-data",
"version": "v3.0.3",
@ -2183,6 +2263,66 @@
],
"time": "2025-03-24T10:02:05+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.13.4",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
"doctrine/collections": "<1.6.8",
"doctrine/common": "<2.13.3 || >=3 <3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
"phpspec/prophecy": "^1.10",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
"autoload": {
"files": [
"src/DeepCopy/deep_copy.php"
],
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"keywords": [
"clone",
"copy",
"duplicate",
"object",
"object graph"
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
},
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
"time": "2025-08-01T08:46:24+00:00"
},
{
"name": "nesbot/carbon",
"version": "3.10.3",
@ -2662,6 +2802,53 @@
],
"time": "2025-08-21T11:53:16+00:00"
},
{
"name": "phpstan/phpdoc-parser",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
"reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"require-dev": {
"doctrine/annotations": "^2.0",
"nikic/php-parser": "^5.3.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^9.6",
"symfony/process": "^5.2"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPStan\\PhpDocParser\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
},
"time": "2025-08-30T15:50:23+00:00"
},
{
"name": "psr/clock",
"version": "1.0.0",
@ -3351,6 +3538,67 @@
},
"time": "2025-09-04T20:59:21+00:00"
},
{
"name": "spatie/laravel-package-tools",
"version": "1.92.7",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-package-tools.git",
"reference": "f09a799850b1ed765103a4f0b4355006360c49a5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/f09a799850b1ed765103a4f0b4355006360c49a5",
"reference": "f09a799850b1ed765103a4f0b4355006360c49a5",
"shasum": ""
},
"require": {
"illuminate/contracts": "^9.28|^10.0|^11.0|^12.0",
"php": "^8.0"
},
"require-dev": {
"mockery/mockery": "^1.5",
"orchestra/testbench": "^7.7|^8.0|^9.0|^10.0",
"pestphp/pest": "^1.23|^2.1|^3.1",
"phpunit/php-code-coverage": "^9.0|^10.0|^11.0",
"phpunit/phpunit": "^9.5.24|^10.5|^11.5",
"spatie/pest-plugin-test-time": "^1.1|^2.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\LaravelPackageTools\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"role": "Developer"
}
],
"description": "Tools for creating Laravel packages",
"homepage": "https://github.com/spatie/laravel-package-tools",
"keywords": [
"laravel-package-tools",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-package-tools/issues",
"source": "https://github.com/spatie/laravel-package-tools/tree/1.92.7"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2025-07-17T15:46:43+00:00"
},
{
"name": "symfony/clock",
"version": "v7.4.0",
@ -7006,66 +7254,6 @@
},
"time": "2024-05-16T03:13:13+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.13.4",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
"doctrine/collections": "<1.6.8",
"doctrine/common": "<2.13.3 || >=3 <3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
"phpspec/prophecy": "^1.10",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
"autoload": {
"files": [
"src/DeepCopy/deep_copy.php"
],
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"keywords": [
"clone",
"copy",
"duplicate",
"object",
"object graph"
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
},
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
"time": "2025-08-01T08:46:24+00:00"
},
{
"name": "nunomaduro/collision",
"version": "v8.8.3",
@ -7920,53 +8108,6 @@
},
"time": "2025-11-21T15:09:14+00:00"
},
{
"name": "phpstan/phpdoc-parser",
"version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495",
"reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"require-dev": {
"doctrine/annotations": "^2.0",
"nikic/php-parser": "^5.3.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^9.6",
"symfony/process": "^5.2"
},
"type": "library",
"autoload": {
"psr-4": {
"PHPStan\\PhpDocParser\\": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0"
},
"time": "2025-08-30T15:50:23+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "12.4.0",

136
config/scramble.php Normal file
View File

@ -0,0 +1,136 @@
<?php
use Dedoc\Scramble\Http\Middleware\RestrictedDocsAccess;
return [
/*
* Your API path. By default, all routes starting with this path will be added to the docs.
* If you need to change this behavior, you can add your custom routes resolver using `Scramble::routes()`.
*/
'api_path' => 'api',
/*
* Your API domain. By default, app domain is used. This is also a part of the default API routes
* matcher, so when implementing your own, make sure you use this config if needed.
*/
'api_domain' => null,
/*
* The path where your OpenAPI specification will be exported.
*/
'export_path' => 'api.json',
'info' => [
/*
* API version.
*/
'version' => env('API_VERSION', '0.0.1'),
/*
* Description rendered on the home page of the API documentation (`/docs/api`).
*/
'description' => '',
],
/*
* Customize Stoplight Elements UI
*/
'ui' => [
/*
* Define the title of the documentation's website. App name is used when this config is `null`.
*/
'title' => null,
/*
* Define the theme of the documentation. Available options are `light`, `dark`, and `system`.
*/
'theme' => 'light',
/*
* Hide the `Try It` feature. Enabled by default.
*/
'hide_try_it' => false,
/*
* Hide the schemas in the Table of Contents. Enabled by default.
*/
'hide_schemas' => false,
/*
* URL to an image that displays as a small square logo next to the title, above the table of contents.
*/
'logo' => '',
/*
* Use to fetch the credential policy for the Try It feature. Options are: omit, include (default), and same-origin
*/
'try_it_credentials_policy' => 'include',
/*
* There are three layouts for Elements:
* - sidebar - (Elements default) Three-column design with a sidebar that can be resized.
* - responsive - Like sidebar, except at small screen sizes it collapses the sidebar into a drawer that can be toggled open.
* - stacked - Everything in a single column, making integrations with existing websites that have their own sidebar or other columns already.
*/
'layout' => 'responsive',
],
/*
* The list of servers of the API. By default, when `null`, server URL will be created from
* `scramble.api_path` and `scramble.api_domain` config variables. When providing an array, you
* will need to specify the local server URL manually (if needed).
*
* Example of non-default config (final URLs are generated using Laravel `url` helper):
*
* ```php
* 'servers' => [
* 'Live' => 'api',
* 'Prod' => 'https://scramble.dedoc.co/api',
* ],
* ```
*/
'servers' => null,
/**
* Determines how Scramble stores the descriptions of enum cases.
* Available options:
* - 'description' Case descriptions are stored as the enum schema's description using table formatting.
* - 'extension' Case descriptions are stored in the `x-enumDescriptions` enum schema extension.
*
* @see https://redocly.com/docs-legacy/api-reference-docs/specification-extensions/x-enum-descriptions
* - false - Case descriptions are ignored.
*/
'enum_cases_description_strategy' => 'description',
/**
* Determines how Scramble stores the names of enum cases.
* Available options:
* - 'names' Case names are stored in the `x-enumNames` enum schema extension.
* - 'varnames' - Case names are stored in the `x-enum-varnames` enum schema extension.
* - false - Case names are not stored.
*/
'enum_cases_names_strategy' => false,
/**
* When Scramble encounters deep objects in query parameters, it flattens the parameters so the generated
* OpenAPI document correctly describes the API. Flattening deep query parameters is relevant until
* OpenAPI 3.2 is released and query string structure can be described properly.
*
* For example, this nested validation rule describes the object with `bar` property:
* `['foo.bar' => ['required', 'int']]`.
*
* When `flatten_deep_query_parameters` is `true`, Scramble will document the parameter like so:
* `{"name":"foo[bar]", "schema":{"type":"int"}, "required":true}`.
*
* When `flatten_deep_query_parameters` is `false`, Scramble will document the parameter like so:
* `{"name":"foo", "schema": {"type":"object", "properties":{"bar":{"type": "int"}}, "required": ["bar"]}, "required":true}`.
*/
'flatten_deep_query_parameters' => true,
'middleware' => [
'web',
RestrictedDocsAccess::class,
],
'extensions' => [],
];

View File

@ -13,7 +13,7 @@ return new class extends Migration
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('username');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');

View File

@ -16,5 +16,6 @@ return [
'failed' => 'These credentials do not match our records.',
'password' => 'The provided password is incorrect.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
'logout_success' => "You have been deconnecte"
];

21
lang/fr/auth.php Normal file
View File

@ -0,0 +1,21 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'Impossible de vous connecter',
'password' => 'Email ou mot de passe incorrect',
'throttle' => 'Trop de tentatives veuillez reessayer dans :seconds seconds.',
'logout_success' => 'Vous êtes bien déconnecté'
];

19
lang/fr/pagination.php Normal file
View File

@ -0,0 +1,19 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Previous',
'next' => 'Next &raquo;',
];

22
lang/fr/passwords.php Normal file
View File

@ -0,0 +1,22 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Lignes de langage pour la réinitialisation du mot de passe
|--------------------------------------------------------------------------
|
| Les lignes suivantes sont les messages par défaut correspondant aux
| différentes raisons possibles renvoyées par le courtier de mots de
| passe lors d'une tentative de mise à jour, comme un token invalide.
|
*/
'reset' => 'Votre mot de passe a été réinitialisé.',
'sent' => 'Nous avons envoyé par e-mail le lien de réinitialisation de votre mot de passe.',
'throttled' => 'Veuillez patienter avant de réessayer.',
'token' => 'Ce jeton de réinitialisation du mot de passe est invalide.',
'user' => "Nous ne trouvons pas dutilisateur avec cette adresse e-mail.",
];

217
lang/fr/validation.php Normal file
View File

@ -0,0 +1,217 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Lignes de langage de validation
|--------------------------------------------------------------------------
|
| Les lignes suivantes contiennent les messages derreur par défaut utilisés
| par la classe validateur. Certaines règles ont plusieurs versions, comme
| les règles de taille. N'hésitez pas à personnaliser chaque message ici.
|
*/
'accepted' => 'Le champ :attribute doit être accepté.',
'accepted_if' => 'Le champ :attribute doit être accepté lorsque :other est :value.',
'active_url' => 'Le champ :attribute doit être une URL valide.',
'after' => 'Le champ :attribute doit être une date postérieure à :date.',
'after_or_equal' => 'Le champ :attribute doit être une date postérieure ou égale à :date.',
'alpha' => 'Le champ :attribute ne doit contenir que des lettres.',
'alpha_dash' => 'Le champ :attribute ne doit contenir que des lettres, chiffres, tirets et underscores.',
'alpha_num' => 'Le champ :attribute ne doit contenir que des lettres et chiffres.',
'any_of' => 'Le champ :attribute est invalide.',
'array' => 'Le champ :attribute doit être un tableau.',
'ascii' => 'Le champ :attribute ne doit contenir que des caractères alphanumériques ASCII simples.',
'before' => 'Le champ :attribute doit être une date antérieure à :date.',
'before_or_equal' => 'Le champ :attribute doit être une date antérieure ou égale à :date.',
'between' => [
'array' => 'Le champ :attribute doit contenir entre :min et :max éléments.',
'file' => 'Le champ :attribute doit être entre :min et :max kilo-octets.',
'numeric' => 'Le champ :attribute doit être entre :min et :max.',
'string' => 'Le champ :attribute doit être entre :min et :max caractères.',
],
'boolean' => 'Le champ :attribute doit être vrai ou faux.',
'can' => 'Le champ :attribute contient une valeur non autorisée.',
'confirmed' => 'La confirmation du champ :attribute ne correspond pas.',
'contains' => 'Le champ :attribute manque une valeur requise.',
'current_password' => 'Le mot de passe est incorrect.',
'date' => 'Le champ :attribute doit être une date valide.',
'date_equals' => 'Le champ :attribute doit être une date égale à :date.',
'date_format' => 'Le champ :attribute doit correspondre au format :format.',
'decimal' => 'Le champ :attribute doit contenir :decimal décimales.',
'declined' => 'Le champ :attribute doit être refusé.',
'declined_if' => 'Le champ :attribute doit être refusé lorsque :other est :value.',
'different' => 'Le champ :attribute et :other doivent être différents.',
'digits' => 'Le champ :attribute doit contenir :digits chiffres.',
'digits_between' => 'Le champ :attribute doit contenir entre :min et :max chiffres.',
'dimensions' => "Le champ :attribute a des dimensions d'image invalides.",
'distinct' => 'Le champ :attribute contient une valeur dupliquée.',
'doesnt_contain' => 'Le champ :attribute ne doit contenir aucun des éléments suivants : :values.',
'doesnt_end_with' => 'Le champ :attribute ne doit pas se terminer par lun des éléments suivants : :values.',
'doesnt_start_with' => 'Le champ :attribute ne doit pas commencer par lun des éléments suivants : :values.',
'email' => 'Le champ :attribute doit être une adresse email valide.',
'encoding' => 'Le champ :attribute doit être encodé en :encoding.',
'ends_with' => 'Le champ :attribute doit se terminer par lun des éléments suivants : :values.',
'enum' => 'La valeur sélectionnée pour :attribute est invalide.',
'exists' => 'La valeur sélectionnée pour :attribute est invalide.',
'extensions' => 'Le champ :attribute doit avoir une extension parmi :values.',
'file' => 'Le champ :attribute doit être un fichier.',
'filled' => 'Le champ :attribute doit avoir une valeur.',
'gt' => [
'array' => 'Le champ :attribute doit contenir plus de :value éléments.',
'file' => 'Le champ :attribute doit être supérieur à :value kilo-octets.',
'numeric' => 'Le champ :attribute doit être supérieur à :value.',
'string' => 'Le champ :attribute doit contenir plus de :value caractères.',
],
'gte' => [
'array' => 'Le champ :attribute doit contenir au moins :value éléments.',
'file' => 'Le champ :attribute doit être supérieur ou égal à :value kilo-octets.',
'numeric' => 'Le champ :attribute doit être supérieur ou égal à :value.',
'string' => 'Le champ :attribute doit contenir au moins :value caractères.',
],
'hex_color' => 'Le champ :attribute doit être une couleur hexadécimale valide.',
'image' => 'Le champ :attribute doit être une image.',
'in' => 'La valeur sélectionnée pour :attribute est invalide.',
'in_array' => 'Le champ :attribute doit exister dans :other.',
'in_array_keys' => 'Le champ :attribute doit contenir au moins une des clés suivantes : :values.',
'integer' => 'Le champ :attribute doit être un entier.',
'ip' => 'Le champ :attribute doit être une adresse IP valide.',
'ipv4' => 'Le champ :attribute doit être une adresse IPv4 valide.',
'ipv6' => 'Le champ :attribute doit être une adresse IPv6 valide.',
'json' => 'Le champ :attribute doit être une chaîne JSON valide.',
'list' => 'Le champ :attribute doit être une liste.',
'lowercase' => 'Le champ :attribute doit être en minuscules.',
'lt' => [
'array' => 'Le champ :attribute doit contenir moins de :value éléments.',
'file' => 'Le champ :attribute doit être inférieur à :value kilo-octets.',
'numeric' => 'Le champ :attribute doit être inférieur à :value.',
'string' => 'Le champ :attribute doit contenir moins de :value caractères.',
],
'lte' => [
'array' => 'Le champ :attribute ne doit pas contenir plus de :value éléments.',
'file' => 'Le champ :attribute doit être inférieur ou égal à :value kilo-octets.',
'numeric' => 'Le champ :attribute doit être inférieur ou égal à :value.',
'string' => 'Le champ :attribute doit contenir au maximum :value caractères.',
],
'mac_address' => 'Le champ :attribute doit être une adresse MAC valide.',
'max' => [
'array' => 'Le champ :attribute ne doit pas contenir plus de :max éléments.',
'file' => 'Le champ :attribute ne doit pas dépasser :max kilo-octets.',
'numeric' => 'Le champ :attribute ne doit pas être supérieur à :max.',
'string' => 'Le champ :attribute ne doit pas dépasser :max caractères.',
],
'max_digits' => 'Le champ :attribute ne doit pas avoir plus de :max chiffres.',
'mimes' => 'Le champ :attribute doit être un fichier de type : :values.',
'mimetypes' => 'Le champ :attribute doit être un fichier de type : :values.',
'min' => [
'array' => 'Le champ :attribute doit contenir au moins :min éléments.',
'file' => 'Le champ :attribute doit être au moins de :min kilo-octets.',
'numeric' => 'Le champ :attribute doit être au moins :min.',
'string' => 'Le champ :attribute doit contenir au moins :min caractères.',
],
'min_digits' => 'Le champ :attribute doit contenir au moins :min chiffres.',
'missing' => 'Le champ :attribute doit être manquant.',
'missing_if' => 'Le champ :attribute doit être manquant lorsque :other est :value.',
'missing_unless' => 'Le champ :attribute doit être manquant sauf si :other vaut :value.',
'missing_with' => 'Le champ :attribute doit être manquant lorsque :values est présent.',
'missing_with_all' => 'Le champ :attribute doit être manquant lorsque :values sont présents.',
'multiple_of' => 'Le champ :attribute doit être un multiple de :value.',
'not_in' => 'La valeur sélectionnée pour :attribute est invalide.',
'not_regex' => 'Le format du champ :attribute est invalide.',
'numeric' => 'Le champ :attribute doit être un nombre.',
'password' => [
'letters' => 'Le champ :attribute doit contenir au moins une lettre.',
'mixed' => 'Le champ :attribute doit contenir au moins une majuscule et une minuscule.',
'numbers' => 'Le champ :attribute doit contenir au moins un chiffre.',
'symbols' => 'Le champ :attribute doit contenir au moins un symbole.',
'uncompromised' => 'Le :attribute fourni apparaît dans une fuite de données. Veuillez en choisir un autre.',
],
'present' => 'Le champ :attribute doit être présent.',
'present_if' => 'Le champ :attribute doit être présent lorsque :other est :value.',
'present_unless' => 'Le champ :attribute doit être présent sauf si :other vaut :value.',
'present_with' => 'Le champ :attribute doit être présent lorsque :values est présent.',
'present_with_all' => 'Le champ :attribute doit être présent lorsque :values sont présents.',
'prohibited' => 'Le champ :attribute est interdit.',
'prohibited_if' => 'Le champ :attribute est interdit lorsque :other vaut :value.',
'prohibited_if_accepted' => 'Le champ :attribute est interdit lorsque :other est accepté.',
'prohibited_if_declined' => 'Le champ :attribute est interdit lorsque :other est refusé.',
'prohibited_unless' => 'Le champ :attribute est interdit sauf si :other est dans :values.',
'prohibits' => 'Le champ :attribute interdit :other dêtre présent.',
'regex' => 'Le format du champ :attribute est invalide.',
'required' => 'Le champ :attribute est obligatoire.',
'required_array_keys' => 'Le champ :attribute doit contenir des entrées pour : :values.',
'required_if' => 'Le champ :attribute est obligatoire lorsque :other vaut :value.',
'required_if_accepted' => 'Le champ :attribute est obligatoire lorsque :other est accepté.',
'required_if_declined' => 'Le champ :attribute est obligatoire lorsque :other est refusé.',
'required_unless' => 'Le champ :attribute est obligatoire sauf si :other est dans :values.',
'required_with' => 'Le champ :attribute est obligatoire lorsque :values est présent.',
'required_with_all' => 'Le champ :attribute est obligatoire lorsque :values sont présents.',
'required_without' => 'Le champ :attribute est obligatoire lorsque :values nest pas présent.',
'required_without_all' => 'Le champ :attribute est obligatoire lorsque aucun de :values nest présent.',
'same' => 'Le champ :attribute doit correspondre à :other.',
'size' => [
'array' => 'Le champ :attribute doit contenir :size éléments.',
'file' => 'Le champ :attribute doit faire :size kilo-octets.',
'numeric' => 'Le champ :attribute doit être :size.',
'string' => 'Le champ :attribute doit contenir :size caractères.',
],
'starts_with' => 'Le champ :attribute doit commencer par lun des éléments suivants : :values.',
'string' => 'Le champ :attribute doit être une chaîne de caractères.',
'timezone' => 'Le champ :attribute doit être un fuseau horaire valide.',
'unique' => 'La valeur du champ :attribute est déjà utilisée.',
'uploaded' => 'Le téléchargement du fichier :attribute a échoué.',
'uppercase' => 'Le champ :attribute doit être en majuscules.',
'url' => 'Le champ :attribute doit être une URL valide.',
'ulid' => 'Le champ :attribute doit être un ULID valide.',
'uuid' => 'Le champ :attribute doit être un UUID valide.',
/*
|--------------------------------------------------------------------------
| Lignes de langage de validation personnalisées
|--------------------------------------------------------------------------
|
| Vous pouvez spécifier ici des messages personnalisés pour les attributs
| en utilisant la convention "attribute.rule" pour nommer les lignes.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'message-personnalisé',
],
],
/*
|--------------------------------------------------------------------------
| Attributs personnalisés
|--------------------------------------------------------------------------
|
| Ces lignes permettent de remplacer les noms d'attributs par des termes
| plus lisibles comme “Adresse E-mail” au lieu de “email”.
|
*/
'attributes' => [],
];

View File

@ -9,6 +9,13 @@ Route::middleware('auth:sanctum')->group(function (): void {
// });
// User
Route::prefix('auth')->group(function (): void {
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
// Route::get('{provider}/redirect', [ProviderRedirectController::class, 'redirect']);
// Route::get('{provider}/callback', [ProviderCallbackController::class, 'callback']);
});
Route::get('auth/me', [AuthController::class, 'me']);
Route::post('auth/logout', [AuthController::class, 'logout']);