diff --git a/app/GraphQL/Mutations/Login.php b/app/GraphQL/Mutations/Login.php new file mode 100644 index 0000000..8a8c2df --- /dev/null +++ b/app/GraphQL/Mutations/Login.php @@ -0,0 +1,35 @@ +attempt($args)) { + throw new Error('Invalid credentials.'); + } + + $user = $guard->user(); + assert($user instanceof User, 'must receive User after successful login'); + + return $user; + } +} diff --git a/app/GraphQL/Mutations/Logout.php b/app/GraphQL/Mutations/Logout.php new file mode 100644 index 0000000..4fe6097 --- /dev/null +++ b/app/GraphQL/Mutations/Logout.php @@ -0,0 +1,27 @@ +user(); + + $guard->logout(); + + return $user; + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index d9fc80f..44e2cbc 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -25,6 +25,12 @@ final class Kernel extends HttpKernel * @var array> */ protected $middlewareGroups = [ + 'web' => [ + \Illuminate\Cookie\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class, + ], 'api' => [ 'throttle:60,1', \Illuminate\Routing\Middleware\SubstituteBindings::class, diff --git a/composer.json b/composer.json index 3de9dfd..087f0ab 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "php": "^8.0.2", "guzzlehttp/guzzle": "^7.2", "laravel/framework": "^9.11", + "laravel/sanctum": "^2.15", "laravel/tinker": "^2.7", "mll-lab/laravel-graphql-playground": "^2", "nuwave/lighthouse": "^5" diff --git a/composer.lock b/composer.lock index 6773e78..c1cf754 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "cbf56aa73706f9fd47f573048dc65957", + "content-hash": "a74cd89eb2d722c2923d9cd5d1caba1c", "packages": [ { "name": "brick/math", @@ -1175,6 +1175,71 @@ }, "time": "2022-06-07T15:09:32+00:00" }, + { + "name": "laravel/sanctum", + "version": "v2.15.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473", + "reference": "31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^6.9|^7.0|^8.0|^9.0", + "illuminate/contracts": "^6.9|^7.0|^8.0|^9.0", + "illuminate/database": "^6.9|^7.0|^8.0|^9.0", + "illuminate/support": "^6.9|^7.0|^8.0|^9.0", + "php": "^7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0", + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2022-04-08T13:39:49+00:00" + }, { "name": "laravel/serializable-closure", "version": "v1.2.0", diff --git a/config/app.php b/config/app.php index 5d26c80..fe0d849 100644 --- a/config/app.php +++ b/config/app.php @@ -157,6 +157,7 @@ Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, + Illuminate\Session\SessionServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, @@ -214,6 +215,7 @@ 'Response' => Illuminate\Support\Facades\Response::class, 'Route' => Illuminate\Support\Facades\Route::class, 'Schema' => Illuminate\Support\Facades\Schema::class, + 'Session' => Illuminate\Support\Facades\Session::class, 'Storage' => Illuminate\Support\Facades\Storage::class, 'Str' => Illuminate\Support\Str::class, 'URL' => Illuminate\Support\Facades\URL::class, diff --git a/config/auth.php b/config/auth.php index f650f29..a9af342 100644 --- a/config/auth.php +++ b/config/auth.php @@ -36,6 +36,11 @@ */ 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + 'api' => [ 'driver' => 'token', 'provider' => 'users', diff --git a/config/graphql-playground.php b/config/graphql-playground.php new file mode 100644 index 0000000..852808f --- /dev/null +++ b/config/graphql-playground.php @@ -0,0 +1,63 @@ + [ + 'uri' => '/graphql-playground', + 'name' => 'graphql-playground', + 'middleware' => ['web'] + // 'prefix' => '', + // 'domain' => 'graphql.' . env('APP_DOMAIN', 'localhost'), + ], + + /* + |-------------------------------------------------------------------------- + | Default GraphQL endpoint + |-------------------------------------------------------------------------- + | + | The default endpoint that the Playground UI is set to. + | It assumes you are running GraphQL on the same domain + | as GraphQL Playground, but can be set to any URL. + | + */ + + 'endpoint' => '/graphql', + + /* + |-------------------------------------------------------------------------- + | Subscription endpoint + |-------------------------------------------------------------------------- + | + | The default subscription endpoint Playground UI uses to connect to. + | Tries to connect to the `endpoint` value if `null` as ws://{{endpoint}} + | + | Example: `ws://your-endpoint` or `wss://your-endpoint` + | + */ + + 'subscriptionEndpoint' => env('GRAPHQL_PLAYGROUND_SUBSCRIPTION_ENDPOINT', null), + + /* + |-------------------------------------------------------------------------- + | Control Playground availability + |-------------------------------------------------------------------------- + | + | Control if the playground is accessible at all. + | This allows you to disable it in certain environments, + | for example you might not want it active in production. + | + */ + + 'enabled' => env('GRAPHQL_PLAYGROUND_ENABLED', true), +]; diff --git a/config/lighthouse.php b/config/lighthouse.php new file mode 100644 index 0000000..84b1589 --- /dev/null +++ b/config/lighthouse.php @@ -0,0 +1,519 @@ + false, to disable the default route + | registration and take full control. + | + */ + + 'route' => [ + /* + * The URI the endpoint responds to, e.g. mydomain.com/graphql. + */ + 'uri' => '/graphql', + + /* + * Lighthouse creates a named route for convenient URL generation and redirects. + */ + 'name' => 'graphql', + + /* + * Beware that middleware defined here runs before the GraphQL execution phase, + * make sure to return spec-compliant responses in case an error is thrown. + */ + 'middleware' => [ + \Nuwave\Lighthouse\Support\Http\Middleware\AcceptJson::class, + + \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + + // Logs in a user if they are authenticated. In contrast to Laravel's 'auth' + // middleware, this delegates auth and permission checks to the field level. + \Nuwave\Lighthouse\Support\Http\Middleware\AttemptAuthentication::class, + + // Logs every incoming GraphQL query. + // \Nuwave\Lighthouse\Support\Http\Middleware\LogGraphQLQueries::class, + ], + + /* + * The `prefix` and `domain` configuration options are optional. + */ + // 'prefix' => '', + // 'domain' => '', + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guard + |-------------------------------------------------------------------------- + | + | The guard to use for authenticating GraphQL requests, if needed. + | Used in directives such as `@guard` or the `AttemptAuthentication` middleware. + | Falls back to the Laravel default if the defined guard is either `null` or not found. + | + */ + + 'guard' => 'sanctum', + + /* + |-------------------------------------------------------------------------- + | Schema Location + |-------------------------------------------------------------------------- + | + | Path to your .graphql schema file. + | Additional schema files may be imported from within that file. + | + */ + + 'schema' => [ + 'register' => base_path('graphql/schema.graphql'), + ], + + /* + |-------------------------------------------------------------------------- + | Schema Cache + |-------------------------------------------------------------------------- + | + | A large part of schema generation consists of parsing and AST manipulation. + | This operation is very expensive, so it is highly recommended enabling + | caching of the final schema to optimize performance of large schemas. + | + */ + + 'cache' => [ + /* + * Setting to true enables schema caching. + */ + 'enable' => env('LIGHTHOUSE_CACHE_ENABLE', 'local' !== env('APP_ENV')), + + /* + * Allowed values: + * - 1: uses the store, key and ttl config values to store the schema as a string in the given cache store. + * - 2: uses the path config value to store the schema in a PHP file allowing OPcache to pick it up. + */ + 'version' => env('LIGHTHOUSE_CACHE_VERSION', 1), + + /* + * Allows using a specific cache store, uses the app's default if set to null. + * Only relevant if version is set to 1. + */ + 'store' => env('LIGHTHOUSE_CACHE_STORE', null), + + /* + * The name of the cache item for the schema cache. + * Only relevant if version is set to 1. + */ + 'key' => env('LIGHTHOUSE_CACHE_KEY', 'lighthouse-schema'), + + /* + * Duration in seconds the schema should remain cached, null means forever. + * Only relevant if version is set to 1. + */ + 'ttl' => env('LIGHTHOUSE_CACHE_TTL', null), + + /* + * File path to store the lighthouse schema. + * Only relevant if version is set to 2. + */ + 'path' => env('LIGHTHOUSE_CACHE_PATH', base_path('bootstrap/cache/lighthouse-schema.php')), + + /* + * Should the `@cache` directive use a tagged cache? + */ + 'tags' => false, + ], + + /* + |-------------------------------------------------------------------------- + | Query Cache + |-------------------------------------------------------------------------- + | + | Caches the result of parsing incoming query strings to boost performance on subsequent requests. + | + */ + + 'query_cache' => [ + /* + * Setting to true enables query caching. + */ + 'enable' => env('LIGHTHOUSE_QUERY_CACHE_ENABLE', true), + + /* + * Allows using a specific cache store, uses the app's default if set to null. + */ + 'store' => env('LIGHTHOUSE_QUERY_CACHE_STORE', null), + + /* + * Duration in seconds (minutes for Laravel pre-5.8) the query should remain cached, null means forever. + */ + 'ttl' => env( + 'LIGHTHOUSE_QUERY_CACHE_TTL', + \Nuwave\Lighthouse\Support\AppVersion::atLeast(5.8) + ? 24 * 60 * 60 // 1 day in seconds + : 24 * 60 // 1 day in minutes + ), + ], + + /* + |-------------------------------------------------------------------------- + | Namespaces + |-------------------------------------------------------------------------- + | + | These are the default namespaces where Lighthouse looks for classes to + | extend functionality of the schema. You may pass in either a string + | or an array, they are tried in order and the first match is used. + | + */ + + 'namespaces' => [ + 'models' => ['App', 'App\\Models'], + 'queries' => 'App\\GraphQL\\Queries', + 'mutations' => 'App\\GraphQL\\Mutations', + 'subscriptions' => 'App\\GraphQL\\Subscriptions', + 'interfaces' => 'App\\GraphQL\\Interfaces', + 'unions' => 'App\\GraphQL\\Unions', + 'scalars' => 'App\\GraphQL\\Scalars', + 'directives' => ['App\\GraphQL\\Directives'], + 'validators' => ['App\\GraphQL\\Validators'], + ], + + /* + |-------------------------------------------------------------------------- + | Security + |-------------------------------------------------------------------------- + | + | Control how Lighthouse handles security related query validation. + | Read more at https://webonyx.github.io/graphql-php/security/ + | + */ + + 'security' => [ + 'max_query_complexity' => \GraphQL\Validator\Rules\QueryComplexity::DISABLED, + 'max_query_depth' => \GraphQL\Validator\Rules\QueryDepth::DISABLED, + 'disable_introspection' => \GraphQL\Validator\Rules\DisableIntrospection::DISABLED, + ], + + /* + |-------------------------------------------------------------------------- + | Pagination + |-------------------------------------------------------------------------- + | + | Set defaults for the pagination features within Lighthouse, such as + | the @paginate directive, or paginated relation directives. + | + */ + + 'pagination' => [ + /* + * Allow clients to query paginated lists without specifying the amount of items. + * Setting this to `null` means clients have to explicitly ask for the count. + */ + 'default_count' => null, + + /* + * Limit the maximum amount of items that clients can request from paginated lists. + * Setting this to `null` means the count is unrestricted. + */ + 'max_count' => null, + ], + + /* + |-------------------------------------------------------------------------- + | Debug + |-------------------------------------------------------------------------- + | + | Control the debug level as described in https://webonyx.github.io/graphql-php/error-handling/ + | Debugging is only applied if the global Laravel debug config is set to true. + | + | When you set this value through an environment variable, use the following reference table: + | 0 => INCLUDE_NONE + | 1 => INCLUDE_DEBUG_MESSAGE + | 2 => INCLUDE_TRACE + | 3 => INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE + | 4 => RETHROW_INTERNAL_EXCEPTIONS + | 5 => RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_DEBUG_MESSAGE + | 6 => RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE + | 7 => RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE + | 8 => RETHROW_UNSAFE_EXCEPTIONS + | 9 => RETHROW_UNSAFE_EXCEPTIONS | INCLUDE_DEBUG_MESSAGE + | 10 => RETHROW_UNSAFE_EXCEPTIONS | INCLUDE_TRACE + | 11 => RETHROW_UNSAFE_EXCEPTIONS | INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE + | 12 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS + | 13 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_DEBUG_MESSAGE + | 14 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE + | 15 => RETHROW_UNSAFE_EXCEPTIONS | RETHROW_INTERNAL_EXCEPTIONS | INCLUDE_TRACE | INCLUDE_DEBUG_MESSAGE + | + */ + + 'debug' => env('LIGHTHOUSE_DEBUG', \GraphQL\Error\DebugFlag::INCLUDE_DEBUG_MESSAGE | \GraphQL\Error\DebugFlag::INCLUDE_TRACE), + + /* + |-------------------------------------------------------------------------- + | Error Handlers + |-------------------------------------------------------------------------- + | + | Register error handlers that receive the Errors that occur during execution + | and handle them. You may use this to log, filter or format the errors. + | The classes must implement \Nuwave\Lighthouse\Execution\ErrorHandler + | + */ + + 'error_handlers' => [ + \Nuwave\Lighthouse\Execution\AuthenticationErrorHandler::class, + \Nuwave\Lighthouse\Execution\AuthorizationErrorHandler::class, + \Nuwave\Lighthouse\Execution\ValidationErrorHandler::class, + \Nuwave\Lighthouse\Execution\ExtensionErrorHandler::class, + \Nuwave\Lighthouse\Execution\ReportingErrorHandler::class, + ], + + /* + |-------------------------------------------------------------------------- + | Field Middleware + |-------------------------------------------------------------------------- + | + | Register global field middleware directives that wrap around every field. + | Execution happens in the defined order, before other field middleware. + | The classes must implement \Nuwave\Lighthouse\Support\Contracts\FieldMiddleware + | + */ + + 'field_middleware' => [ + \Nuwave\Lighthouse\Schema\Directives\TrimDirective::class, + \Nuwave\Lighthouse\Schema\Directives\ConvertEmptyStringsToNullDirective::class, + \Nuwave\Lighthouse\Schema\Directives\SanitizeDirective::class, + \Nuwave\Lighthouse\Validation\ValidateDirective::class, + \Nuwave\Lighthouse\Schema\Directives\TransformArgsDirective::class, + \Nuwave\Lighthouse\Schema\Directives\SpreadDirective::class, + \Nuwave\Lighthouse\Schema\Directives\RenameArgsDirective::class, + \Nuwave\Lighthouse\Schema\Directives\DropArgsDirective::class, + ], + + /* + |-------------------------------------------------------------------------- + | Global ID + |-------------------------------------------------------------------------- + | + | The name that is used for the global id field on the Node interface. + | When creating a Relay compliant server, this must be named "id". + | + */ + + 'global_id_field' => 'id', + + /* + |-------------------------------------------------------------------------- + | Persisted Queries + |-------------------------------------------------------------------------- + | + | Lighthouse supports Automatic Persisted Queries (APQ), compatible with the + | [Apollo implementation](https://www.apollographql.com/docs/apollo-server/performance/apq). + | You may set this flag to either process or deny these queries. + | + */ + + 'persisted_queries' => true, + + /* + |-------------------------------------------------------------------------- + | Transactional Mutations + |-------------------------------------------------------------------------- + | + | If set to true, built-in directives that mutate models will be + | wrapped in a transaction to ensure atomicity. + | + */ + + 'transactional_mutations' => true, + + /* + |-------------------------------------------------------------------------- + | Mass Assignment Protection + |-------------------------------------------------------------------------- + | + | If set to true, mutations will use forceFill() over fill() when populating + | a model with arguments in mutation directives. Since GraphQL constrains + | allowed inputs by design, mass assignment protection is not needed. + | + */ + + 'force_fill' => true, + + /* + |-------------------------------------------------------------------------- + | Batchload Relations + |-------------------------------------------------------------------------- + | + | If set to true, relations marked with directives like @hasMany or @belongsTo + | will be optimized by combining the queries through the BatchLoader. + | + */ + + 'batchload_relations' => true, + + /* + |-------------------------------------------------------------------------- + | Shortcut Foreign Key Selection + |-------------------------------------------------------------------------- + | + | If set to true, Lighthouse will shortcut queries where the client selects only the + | foreign key pointing to a related model. Only works if the related model's primary + | key field is called exactly `id` for every type in your schema. + | + */ + + 'shortcut_foreign_key_selection' => false, + + /* + |-------------------------------------------------------------------------- + | Non-Null Pagination Results + |-------------------------------------------------------------------------- + | + | If set to true, the generated result type of paginated lists will be marked + | as non-nullable. This is generally more convenient for clients, but will + | cause validation errors to bubble further up in the result. + | + | This setting will be removed and always behave as if it were true in v6. + | + */ + + 'non_null_pagination_results' => false, + + /* + |-------------------------------------------------------------------------- + | Unbox BenSampo\Enum\Enum instances + |-------------------------------------------------------------------------- + | + | If set to true, Lighthouse will extract the internal $value from instances of + | BenSampo\Enum\Enum before passing it to ArgBuilderDirective::handleBuilder(). + | + | This setting will be removed and always behave as if it were false in v6. + | + | It is only here to preserve compatibility, e.g. when expecting the internal + | value to be passed to a scope when using @scope, but not needed due to Laravel + | calling the Enum's __toString() method automagically when used in a query. + | + */ + + 'unbox_bensampo_enum_enum_instances' => true, + + /* + |-------------------------------------------------------------------------- + | GraphQL Subscriptions + |-------------------------------------------------------------------------- + | + | Here you can define GraphQL subscription broadcaster and storage drivers + | as well their required configuration options. + | + */ + + 'subscriptions' => [ + /* + * Determines if broadcasts should be queued by default. + */ + 'queue_broadcasts' => env('LIGHTHOUSE_QUEUE_BROADCASTS', true), + + /* + * Determines the queue to use for broadcasting queue jobs. + */ + 'broadcasts_queue_name' => env('LIGHTHOUSE_BROADCASTS_QUEUE_NAME', null), + + /* + * Default subscription storage. + * + * Any Laravel supported cache driver options are available here. + */ + 'storage' => env('LIGHTHOUSE_SUBSCRIPTION_STORAGE', 'redis'), + + /* + * Default subscription storage time to live in seconds. + * + * Indicates how long a subscription can be active before it's automatically removed from storage. + * Setting this to `null` means the subscriptions are stored forever. This may cause + * stale subscriptions to linger indefinitely in case cleanup fails for any reason. + */ + 'storage_ttl' => env('LIGHTHOUSE_SUBSCRIPTION_STORAGE_TTL', null), + + /* + * Default subscription broadcaster. + */ + 'broadcaster' => env('LIGHTHOUSE_BROADCASTER', 'pusher'), + + /* + * Subscription broadcasting drivers with config options. + */ + 'broadcasters' => [ + 'log' => [ + 'driver' => 'log', + ], + 'pusher' => [ + 'driver' => 'pusher', + 'routes' => \Nuwave\Lighthouse\Subscriptions\SubscriptionRouter::class . '@pusher', + 'connection' => 'pusher', + ], + 'echo' => [ + 'driver' => 'echo', + 'connection' => env('LIGHTHOUSE_SUBSCRIPTION_REDIS_CONNECTION', 'default'), + 'routes' => \Nuwave\Lighthouse\Subscriptions\SubscriptionRouter::class . '@echoRoutes', + ], + ], + + /* + * Controls the format of the extensions response. + * Allowed values: 1, 2 + */ + 'version' => env('LIGHTHOUSE_SUBSCRIPTION_VERSION', 1), + + /* + * Should the subscriptions extension be excluded when the response has no subscription channel? + * This optimizes performance by sending less data, but clients must anticipate this appropriately. + * Will default to true in v6 and be removed in v7. + */ + 'exclude_empty' => env('LIGHTHOUSE_SUBSCRIPTION_EXCLUDE_EMPTY', false), + ], + + /* + |-------------------------------------------------------------------------- + | Defer + |-------------------------------------------------------------------------- + | + | Configuration for the experimental @defer directive support. + | + */ + + 'defer' => [ + /* + * Maximum number of nested fields that can be deferred in one query. + * Once reached, remaining fields will be resolved synchronously. + * 0 means unlimited. + */ + 'max_nested_fields' => 0, + + /* + * Maximum execution time for deferred queries in milliseconds. + * Once reached, remaining fields will be resolved synchronously. + * 0 means unlimited. + */ + 'max_execution_ms' => 0, + ], + + /* + |-------------------------------------------------------------------------- + | Apollo Federation + |-------------------------------------------------------------------------- + | + | Lighthouse can act as a federated service: https://www.apollographql.com/docs/federation/federation-spec. + | + */ + + 'federation' => [ + /* + * Location of resolver classes when resolving the `_entities` field. + */ + 'entities_resolver_namespace' => 'App\\GraphQL\\Entities', + ], +]; diff --git a/config/sanctum.php b/config/sanctum.php new file mode 100644 index 0000000..12b41ba --- /dev/null +++ b/config/sanctum.php @@ -0,0 +1,47 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1,127.0.0.1:8000,::1')), + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. If this value is null, personal access tokens do + | not expire. This won't tweak the lifetime of first-party sessions. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'verify_csrf_token' => \Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class, + 'encrypt_cookies' => \Illuminate\Cookie\Middleware\EncryptCookies::class, + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..4e0f66c --- /dev/null +++ b/config/session.php @@ -0,0 +1,201 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION', null), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | While using one of the framework's cache driven session backends you may + | list a cache store that should be used for these sessions. This value + | must match with one of the application's configured cache "stores". + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE', null), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" since this is a secure default value. + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => 'lax', + +]; diff --git a/graphql/schema.graphql b/graphql/schema.graphql index 6772060..c10de1f 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -4,4 +4,12 @@ scalar Date @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\Date") "A datetime string with format `Y-m-d H:i:s`, e.g. `2018-05-23 13:43:32`." scalar DateTime @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime") +type Mutation { + "Log in to a new session and get the user." + login(email: String!, password: String!): User! + + "Log out from the current session, showing the user one last time." + logout: User @guard +} + #import models/*.graphql diff --git a/resources/views/vendor/graphql-playground/index.blade.php b/resources/views/vendor/graphql-playground/index.blade.php new file mode 100644 index 0000000..e6e0873 --- /dev/null +++ b/resources/views/vendor/graphql-playground/index.blade.php @@ -0,0 +1,41 @@ + + + + + + + + + GraphQL Playground + + + + + + + + +
+ + + + diff --git a/storage/framework/sessions/.gitignore b/storage/framework/sessions/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/sessions/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore