* * @throws OAuthServerException */ public function issue( User $user, string $clientId, string $clientSecret, array $scopes, ?string $name = null ): array { $response = $this->server()->respondToAccessTokenRequest( $this->createRequest($user, $clientId, $clientSecret, $scopes, $name), app(ResponseInterface::class) ); return json_decode((string) $response->getBody(), true); } /** * Cheap pre-check so the controller can reject bad client credentials * before it creates the user. Same repository call the grant makes. */ public function validateClient(string $clientId, string $clientSecret): bool { if ($clientId === '' || $clientSecret === '') { return false; } return app(ClientRepository::class)->validateClient( $clientId, $clientSecret, AppRegisterGrant::IDENTIFIER ); } /** * @param string[] $scopes */ protected function createRequest( User $user, string $clientId, string $clientSecret, array $scopes, ?string $name ): ServerRequestInterface { return (new PsrHttpFactory)->createRequest(Request::create(config('app.url'), 'POST', [ 'grant_type' => AppRegisterGrant::IDENTIFIER, 'client_id' => $clientId, 'client_secret' => $clientSecret, 'user_id' => (string) $user->getKey(), 'scope' => implode(' ', $scopes), 'name' => $name, ])); } protected function server(): AuthorizationServer { if ($this->server) { return $this->server; } $server = new AuthorizationServer( app(ClientRepository::class), app(AccessTokenRepository::class), app(ScopeRepository::class), $this->privateKey(), Passport::tokenEncryptionKey(app('encrypter')), new BearerTokenResponse ); $server->setDefaultScope(Passport::$defaultScope); $server->revokeRefreshTokens(Passport::$revokeRefreshTokenAfterUse); $grant = new AppRegisterGrant(app(RefreshTokenRepository::class)); $grant->setRefreshTokenTTL(Passport::refreshTokensExpireIn()); $server->enableGrantType($grant, Passport::tokensExpireIn()); return $this->server = $server; } /** * Same resolution as PassportServiceProvider::makeCryptKey('private'). */ protected function privateKey(): CryptKey { $key = str_replace('\\n', "\n", config('passport.private_key') ?? ''); if (! $key) { $key = 'file://'.Passport::keyPath('oauth-private.key'); } return new CryptKey($key, null, Passport::$validateKeyPermissions); } }