hentryService = $hentryService; $this->hcardService = $hcardService; $this->updateService = $updateService; } /** * This function receives an API request, verifies the authenticity * then passes over the info to the relevant Service class. */ public function post(Request $request): JsonResponse { $this->logMicropubRequest($request->except('token_data')); /** @var Token $tokenData */ $tokenData = $request->input('token_data'); if (($request->input('h') === 'entry') || ($request->input('type.0') === 'h-entry')) { $scopes = $tokenData['scope']; if (is_string($scopes)) { $scopes = explode(' ', $scopes); } if (! in_array('create', $scopes, true)) { $micropubResponses = new MicropubResponses; return $micropubResponses->insufficientScopeResponse(); } $location = $this->hentryService->process($request->all(), $tokenData['client_id']); return response()->json([ 'response' => 'created', 'location' => $location, ], 201)->header('Location', $location); } if ($request->input('h') === 'card' || $request->input('type.0') === 'h-card') { $scopes = $tokenData['scope']; if (is_string($scopes)) { $scopes = explode(' ', $scopes); } if (! in_array('create', $scopes)) { $micropubResponses = new MicropubResponses; return $micropubResponses->insufficientScopeResponse(); } $location = $this->hcardService->process($request->all()); return response()->json([ 'response' => 'created', 'location' => $location, ], 201)->header('Location', $location); } if ($request->input('action') === 'update') { $scopes = $tokenData['scope']; if (is_string($scopes)) { $scopes = explode(' ', $scopes); } if (! in_array('update', $scopes)) { $micropubResponses = new MicropubResponses; return $micropubResponses->insufficientScopeResponse(); } return $this->updateService->process($request->all()); } return response()->json([ 'response' => 'error', 'error_description' => 'unsupported_request_type', ], 500); } /** * Respond to a GET request to the micropub endpoint. * * A GET request has been made to `api/post` with an accompanying * token, here we check whether the token is valid and respond * appropriately. Further if the request has the query parameter * syndicate-to we respond with the known syndication endpoints. */ public function get(Request $request): JsonResponse { if ($request->input('q') === 'syndicate-to') { return response()->json([ 'syndicate-to' => SyndicationTarget::all(), ]); } if ($request->input('q') === 'config') { return response()->json([ 'syndicate-to' => SyndicationTarget::all(), 'media-endpoint' => route('media-endpoint'), ]); } if ($request->has('q') && str_starts_with($request->input('q'), 'geo:')) { preg_match_all( '/([0-9.\-]+)/', $request->input('q'), $matches ); $distance = (count($matches[0]) === 3) ? 100 * $matches[0][2] : 1000; $places = Place::near( (object) ['latitude' => $matches[0][0], 'longitude' => $matches[0][1]], $distance )->get(); return response()->json([ 'response' => 'places', 'places' => $places, ]); } // default response is just to return the token data /** @var Token $tokenData */ $tokenData = $request->input('token_data'); return response()->json([ 'response' => 'token', 'token' => [ 'me' => $tokenData['me'], 'scope' => $tokenData['scope'], 'client_id' => $tokenData['client_id'], ], ]); } /** * Save the details of the micropub request to a log file. */ private function logMicropubRequest(array $request): void { $logger = new Logger('micropub'); $logger->pushHandler(new StreamHandler(storage_path('logs/micropub.log'))); $logger->debug('MicropubLog', $request); } }