Merge branch 'feature/better-places' into develop
This commit is contained in:
commit
5ffcee06c0
7 changed files with 208 additions and 87 deletions
|
@ -204,34 +204,37 @@ class MicropubClientController extends Controller
|
|||
*/
|
||||
public function postNewPlace(Request $request)
|
||||
{
|
||||
if ($request->session()->has('token') === false) {
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'error_description' => 'No known token',
|
||||
], 400);
|
||||
}
|
||||
$domain = $request->session()->get('me');
|
||||
$token = $request->session()->get('token');
|
||||
|
||||
$micropubEndpoint = $this->indieAuthService->discoverMicropubEndpoint($domain, $this->indieClient);
|
||||
if (! $micropubEndpoint) {
|
||||
return (new Response(json_encode([
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => 'Could not determine the micropub endpoint.',
|
||||
]), 400))
|
||||
->header('Content-Type', 'application/json');
|
||||
'error_description' => 'Could not determine the micropub endpoint.',
|
||||
], 400);
|
||||
}
|
||||
|
||||
$place = $this->postPlaceRequest($request, $micropubEndpoint, $token);
|
||||
if ($place === false) {
|
||||
return (new Response(json_encode([
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'message' => 'Unable to create the new place',
|
||||
]), 400))
|
||||
->header('Content-Type', 'application/json');
|
||||
'error_description' => 'Unable to create the new place',
|
||||
], 400);
|
||||
}
|
||||
|
||||
return (new Response(json_encode([
|
||||
return response()->json([
|
||||
'url' => $place,
|
||||
'name' => $request->input('place-name'),
|
||||
'latitude' => $request->input('place-latitude'),
|
||||
'longitude' => $request->input('place-longitude'),
|
||||
]), 200))
|
||||
->header('Content-Type', 'application/json');
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,7 +266,7 @@ class MicropubClientController extends Controller
|
|||
'headers' => $headers,
|
||||
]);
|
||||
} catch (ClientException $e) {
|
||||
//not sure yet...
|
||||
return false;
|
||||
}
|
||||
if ($response->getStatusCode() == 201) {
|
||||
return $response->getHeader('Location')[0];
|
||||
|
@ -285,12 +288,22 @@ class MicropubClientController extends Controller
|
|||
$latitude,
|
||||
$longitude
|
||||
) {
|
||||
if ($request->session()->has('token') === false) {
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'error_description' => 'No known token',
|
||||
], 400);
|
||||
}
|
||||
$domain = $request->session()->get('me');
|
||||
$token = $request->session()->get('token');
|
||||
|
||||
$micropubEndpoint = $this->indieAuthService->discoverMicropubEndpoint($domain, $this->indieClient);
|
||||
|
||||
if (! $micropubEndpoint) {
|
||||
return;
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'error_description' => 'No known endpoint',
|
||||
], 400);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -299,7 +312,10 @@ class MicropubClientController extends Controller
|
|||
'query' => ['q' => 'geo:' . $latitude . ',' . $longitude],
|
||||
]);
|
||||
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
|
||||
return;
|
||||
return response()->json([
|
||||
'error' => true,
|
||||
'error_description' => 'The endpoint returned a non-good response',
|
||||
], 400);
|
||||
}
|
||||
|
||||
return (new Response($response->getBody(), 200))
|
||||
|
|
|
@ -57,54 +57,43 @@ class MicropubController extends Controller
|
|||
if (array_search('post', $scopes) !== false) {
|
||||
$clientId = $tokenData->getClaim('client_id');
|
||||
if (($request->input('h') == 'entry') || ($request->input('type')[0] == 'h-entry')) {
|
||||
try {
|
||||
$note = $this->noteService->createNote($request, $clientId);
|
||||
$content = <<<EOD
|
||||
{
|
||||
"response": "created",
|
||||
"location": "$note->longurl"
|
||||
} catch (Exception $exception) {
|
||||
return response()->json(['error' => true], 400);
|
||||
}
|
||||
EOD;
|
||||
|
||||
return (new Response($content, 201))
|
||||
->header('Location', $note->longurl)
|
||||
->header('Content-Type', 'application/json');
|
||||
return response()->json([
|
||||
'response' => 'created',
|
||||
'location' => $note->longurl
|
||||
], 201)->header('Location', $note->longurl);
|
||||
}
|
||||
if ($request->input('h') == 'card' || $request->input('type')[0] == 'h-card') {
|
||||
try {
|
||||
$place = $this->placeService->createPlace($request);
|
||||
$content = <<<EOD
|
||||
{
|
||||
"response": "created",
|
||||
"location": "$place->longurl"
|
||||
} catch (Exception $exception) {
|
||||
return response()->json(['error' => true], 400);
|
||||
}
|
||||
EOD;
|
||||
|
||||
return (new Response($content, 201))
|
||||
->header('Location', $place->longurl)
|
||||
->header('Content-Type', 'application/json');
|
||||
return response()->json([
|
||||
'response' => 'created',
|
||||
'location' => $place->longurl
|
||||
], 201)->header('Location', $place->longurl);
|
||||
}
|
||||
}
|
||||
}
|
||||
$content = <<<'EOD'
|
||||
{
|
||||
"response": "error",
|
||||
"error": "invalid_token",
|
||||
"error_description": "The token provided is not valid or does not have the necessary scope",
|
||||
}
|
||||
EOD;
|
||||
|
||||
return (new Response($content, 400))
|
||||
->header('Content-Type', 'application/json');
|
||||
return response()->json([
|
||||
'response' => 'error',
|
||||
'error' => 'invalid_token',
|
||||
'error_description' => 'The token provided is not valid or does not have the necessary scope'
|
||||
], 400);
|
||||
}
|
||||
$content = <<<'EOD'
|
||||
{
|
||||
"response": "error",
|
||||
"error": "no_token",
|
||||
"error_description": "No OAuth token sent with request"
|
||||
}
|
||||
EOD;
|
||||
|
||||
return (new Response($content, 400))
|
||||
->header('Content-Type', 'application/json');
|
||||
return response()->json([
|
||||
'response' => 'error',
|
||||
'error' => 'no_token',
|
||||
'error_description' => 'No OAuth token sent with request'
|
||||
], 400);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,9 +4,7 @@ namespace App;
|
|||
|
||||
use DB;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Phaza\LaravelPostgis\Geometries\Point;
|
||||
use MartinBean\Database\Eloquent\Sluggable;
|
||||
use Phaza\LaravelPostgis\Geometries\Polygon;
|
||||
use Phaza\LaravelPostgis\Eloquent\PostgisTrait;
|
||||
|
||||
class Place extends Model
|
||||
|
@ -33,8 +31,8 @@ class Place extends Model
|
|||
* @var array
|
||||
*/
|
||||
protected $postgisFields = [
|
||||
'location' => Point::class,
|
||||
'polygon' => Polygon::class,
|
||||
'location',
|
||||
'polygon',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,21 +16,26 @@ class PlaceService
|
|||
*/
|
||||
public function createPlace(Request $request)
|
||||
{
|
||||
//we’ll either have latitude and longitude sent together in a
|
||||
//geo-url (micropub), or seperatley (/admin)
|
||||
if ($request->input('geo') !== null) {
|
||||
$parts = explode(':', $request->input('geo'));
|
||||
if ($request->header('Content-Type') == 'application/json') {
|
||||
$name = $request->input('properties.name');
|
||||
$description = $request->input('properties.description') ?? null;
|
||||
$geo = $request->input('properties.geo');
|
||||
} else {
|
||||
$name = $request->input('name');
|
||||
$description = $request->input('description');
|
||||
$geo = $request->input('geo');
|
||||
}
|
||||
$parts = explode(':', $geo);
|
||||
$latlng = explode(',', $parts[1]);
|
||||
$latitude = $latlng[0];
|
||||
$longitude = $latlng[1];
|
||||
}
|
||||
if ($request->input('latitude') !== null) {
|
||||
$latitude = $request->input('latitude');
|
||||
$longitude = $request->input('longitude');
|
||||
}
|
||||
$place = new Place();
|
||||
$place->name = $request->input('name');
|
||||
$place->description = $request->input('description');
|
||||
$place->name = $name;
|
||||
$place->description = $description;
|
||||
$place->location = new Point((float) $latitude, (float) $longitude);
|
||||
$place->save();
|
||||
|
||||
|
|
|
@ -12,11 +12,11 @@ if ('geolocation' in navigator) {
|
|||
function getLocation() {
|
||||
navigator.geolocation.getCurrentPosition(function (position) {
|
||||
//the locate button has been clicked so add the places/map
|
||||
addPlaces(position.coords.latitude, position.coords.longitude);
|
||||
addPlacesMap(position.coords.latitude, position.coords.longitude);
|
||||
});
|
||||
}
|
||||
|
||||
function addPlaces(latitude, longitude) {
|
||||
function addPlacesMap(latitude, longitude) {
|
||||
//get the nearby places
|
||||
fetch('/places/near/' + latitude + '/' + longitude, {
|
||||
credentials: 'same-origin',
|
||||
|
@ -24,6 +24,10 @@ function addPlaces(latitude, longitude) {
|
|||
}).then(function (response) {
|
||||
return response.json();
|
||||
}).then(function (j) {
|
||||
if (j.error == true) {
|
||||
alertify.reset();
|
||||
alertify.error(j.error_description);
|
||||
}
|
||||
if (j.length > 0) {
|
||||
var i;
|
||||
var places = [];
|
||||
|
@ -195,17 +199,13 @@ function addMap(latitude, longitude, places) {
|
|||
method: 'post',
|
||||
body: formData
|
||||
})
|
||||
.then(function (response) {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return Promise.resolve(response);
|
||||
} else {
|
||||
return Promise.reject(new Error(response.statusText));
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (placeJson) {
|
||||
if (placeJson.error == true) {
|
||||
throw new Error(placeJson.error_description);
|
||||
}
|
||||
//create the slug from the url
|
||||
var urlParts = placeJson.split('/');
|
||||
var slug = urlParts.pop();
|
||||
|
@ -247,7 +247,8 @@ function addMap(latitude, longitude, places) {
|
|||
//make selected
|
||||
selectPlace(slug);
|
||||
}).catch(function (placeError) {
|
||||
console.error(placeError);
|
||||
alertify.reset();
|
||||
alertify.error(placeError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* global L */
|
||||
/* global L, alertify */
|
||||
if ('geolocation' in navigator) {
|
||||
var button = document.querySelector('#locate');
|
||||
if (button.addEventListener) {
|
||||
|
@ -12,11 +12,11 @@ if ('geolocation' in navigator) {
|
|||
function getLocation() {
|
||||
navigator.geolocation.getCurrentPosition(function (position) {
|
||||
//the locate button has been clicked so add the places/map
|
||||
addPlaces(position.coords.latitude, position.coords.longitude);
|
||||
addPlacesMap(position.coords.latitude, position.coords.longitude);
|
||||
});
|
||||
}
|
||||
|
||||
function addPlaces(latitude, longitude) {
|
||||
function addPlacesMap(latitude, longitude) {
|
||||
//get the nearby places
|
||||
fetch('/places/near/' + latitude + '/' + longitude, {
|
||||
credentials: 'same-origin',
|
||||
|
@ -24,6 +24,10 @@ function addPlaces(latitude, longitude) {
|
|||
}).then(function (response) {
|
||||
return response.json();
|
||||
}).then(function (j) {
|
||||
if (j.error == true) {
|
||||
alertify.reset();
|
||||
alertify.error(j.error_description);
|
||||
}
|
||||
if (j.length > 0) {
|
||||
var i;
|
||||
var places = [];
|
||||
|
@ -195,17 +199,13 @@ function addMap(latitude, longitude, places) {
|
|||
method: 'post',
|
||||
body: formData
|
||||
})
|
||||
.then(function (response) {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
return Promise.resolve(response);
|
||||
} else {
|
||||
return Promise.reject(new Error(response.statusText));
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (placeJson) {
|
||||
if (placeJson.error == true) {
|
||||
throw new Error(placeJson.error_description);
|
||||
}
|
||||
//create the slug from the url
|
||||
var urlParts = placeJson.split('/');
|
||||
var slug = urlParts.pop();
|
||||
|
@ -247,7 +247,8 @@ function addMap(latitude, longitude, places) {
|
|||
//make selected
|
||||
selectPlace(slug);
|
||||
}).catch(function (placeError) {
|
||||
console.error(placeError);
|
||||
alertify.reset();
|
||||
alertify.error(placeError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -116,6 +116,103 @@ class MicropubTest extends TestCase
|
|||
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
|
||||
)->seeJson([
|
||||
'response' => 'created'
|
||||
])->assertResponseStatus(201);
|
||||
}
|
||||
|
||||
public function testMicropubJSONRequestCreateNewNoteWithoutToken()
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
$note = $faker->text;
|
||||
$this->json(
|
||||
'POST',
|
||||
$this->appurl . '/api/post',
|
||||
[
|
||||
'type' => ['h-entry'],
|
||||
'properties' => [
|
||||
'content' => [$note],
|
||||
],
|
||||
]
|
||||
)->seeJson([
|
||||
'response' => 'error',
|
||||
'error' => 'no_token'
|
||||
])->assertResponseStatus(400);
|
||||
}
|
||||
|
||||
public function testMicropubJSONRequestCreateNewNoteWithInvalidToken()
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
$note = $faker->text;
|
||||
$this->json(
|
||||
'POST',
|
||||
$this->appurl . '/api/post',
|
||||
[
|
||||
'type' => ['h-entry'],
|
||||
'properties' => [
|
||||
'content' => [$note],
|
||||
],
|
||||
],
|
||||
['HTTP_Authorization' => 'Bearer ' . $this->getInvalidToken()]
|
||||
)->seeJson([
|
||||
'response' => 'error',
|
||||
'error' => 'invalid_token'
|
||||
]);
|
||||
}
|
||||
|
||||
public function testMicropubJSONRequestCreateNewPlace()
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
$this->json(
|
||||
'POST',
|
||||
$this->appurl . '/api/post',
|
||||
[
|
||||
'type' => ['h-card'],
|
||||
'properties' => [
|
||||
'name' => $faker->name,
|
||||
'geo' => 'geo:' . $faker->latitude . ',' . $faker->longitude
|
||||
],
|
||||
],
|
||||
['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
|
||||
)->seeJson([
|
||||
'response' => 'created'
|
||||
])->assertResponseStatus(201);
|
||||
}
|
||||
|
||||
public function testMicropubJSONRequestCreateNewPlaceWithoutToken()
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
$this->json(
|
||||
'POST',
|
||||
$this->appurl . '/api/post',
|
||||
[
|
||||
'type' => ['h-entry'],
|
||||
'properties' => [
|
||||
'name' => $faker->name,
|
||||
'geo' => 'geo:' . $faker->latitude . ',' . $faker->longitude
|
||||
],
|
||||
]
|
||||
)->seeJson([
|
||||
'response' => 'error',
|
||||
'error' => 'no_token'
|
||||
])->assertResponseStatus(400);
|
||||
}
|
||||
|
||||
public function testMicropubJSONRequestCreateNewPlaceWithInvalidToken()
|
||||
{
|
||||
$faker = \Faker\Factory::create();
|
||||
$this->json(
|
||||
'POST',
|
||||
$this->appurl . '/api/post',
|
||||
[
|
||||
'type' => ['h-entry'],
|
||||
'properties' => [
|
||||
'name' => $faker->name,
|
||||
'geo' => 'geo:' . $faker->latitude . ',' . $faker->longitude
|
||||
],
|
||||
],
|
||||
['HTTP_Authorization' => 'Bearer ' . $this->getInvalidToken()]
|
||||
)->seeJson([
|
||||
'response' => 'error',
|
||||
'error' => 'invalid_token'
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -132,4 +229,18 @@ class MicropubTest extends TestCase
|
|||
|
||||
return $token;
|
||||
}
|
||||
|
||||
private function getInvalidToken()
|
||||
{
|
||||
$signer = new Sha256();
|
||||
$token = (new Builder())
|
||||
->set('client_id', 'https://quill.p3k.io')
|
||||
->set('me', 'https://jonnybarnes.localhost')
|
||||
->set('scope', 'view')
|
||||
->set('issued_at', time())
|
||||
->sign($signer, env('APP_KEY'))
|
||||
->getToken();
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue