diff --git a/.env.example b/.env.example
index 57ea1e36..72c19df3 100644
--- a/.env.example
+++ b/.env.example
@@ -52,3 +52,5 @@ TWITTER_ACCESS_TOKEN_SECRET=
SCOUT_DRIVER=pgsql
PIWIK=false
+
+PSYSH_CONFIG=tinker.config.php
diff --git a/app/Exceptions/InvalidTokenException.php b/app/Exceptions/InvalidTokenException.php
new file mode 100644
index 00000000..8184cfa7
--- /dev/null
+++ b/app/Exceptions/InvalidTokenException.php
@@ -0,0 +1,13 @@
+client = $client ?? new Client();
- $this->tokenService = $tokenService ?? new TokenService();
}
/**
@@ -90,37 +80,6 @@ class IndieAuthController extends Controller
return redirect(route('micropub-client'));
}
-/*
- $tokenEndpoint = $this->indieAuthService->getTokenEndpoint($request->input('me'));
- if ($tokenEndpoint === false) {
- return redirect(route('micropub-client'))->with(
- 'error',
- 'Unable to determine token endpoint'
- );
- }
- $data = [
- 'endpoint' => $tokenEndpoint,
- 'code' => $request->input('code'),
- 'me' => $request->input('me'),
- 'redirect_url' => route('indieauth-callback'),
- 'client_id' => route('micropub-client'),
- 'state' => $request->input('state'),
- ];
- $token = $this->indieAuthService->getAccessToken($data);
-
- if (array_key_exists('access_token', $token)) {
- $request->session()->put('me', $token['me']);
- $request->session()->put('token', $token['access_token']);
-
- return redirect(route('micropub-client'));
- }
-
- return redirect(route('micropub-client'))->with(
- 'error',
- 'Unable to get a token from the endpoint'
- );
-*/
-
/**
* Log out the user, flush the session data.
*
@@ -132,42 +91,4 @@ class IndieAuthController extends Controller
return redirect(route('micropub-client'));
}
-
- /**
- * If the user has auth’d via IndieAuth, issue a valid token.
- *
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\Http\Response
- */
- public function tokenEndpoint(Request $request)
- {
- $authData = [
- 'code' => $request->input('code'),
- 'me' => $request->input('me'),
- 'redirect_url' => $request->input('redirect_uri'),
- 'client_id' => $request->input('client_id'),
- 'state' => $request->input('state'),
- ];
- $auth = $this->indieAuthService->verifyIndieAuthCode($authData);
- if (array_key_exists('me', $auth)) {
- $scope = $auth['scope'] ?? '';
- $tokenData = [
- 'me' => $request->input('me'),
- 'client_id' => $request->input('client_id'),
- 'scope' => $auth['scope'],
- ];
- $token = $this->tokenService->getNewToken($tokenData);
- $content = http_build_query([
- 'me' => $request->input('me'),
- 'scope' => $scope,
- 'access_token' => $token,
- ]);
-
- return response($content)
- ->header('Content-Type', 'application/x-www-form-urlencoded');
- }
- $content = 'There was an error verifying the authorisation code.';
-
- return response($content, 400);
- }
}
diff --git a/app/Http/Controllers/MicropubController.php b/app/Http/Controllers/MicropubController.php
index 65ddb982..2aba67cc 100644
--- a/app/Http/Controllers/MicropubController.php
+++ b/app/Http/Controllers/MicropubController.php
@@ -3,8 +3,9 @@
namespace App\Http\Controllers;
use Ramsey\Uuid\Uuid;
-use App\{Media, Place};
+use App\{Media, Note, Place};
use Illuminate\Http\{Request, Response};
+use App\Exceptions\InvalidTokenException;
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
use App\Services\{NoteService, PlaceService, TokenService};
@@ -49,7 +50,7 @@ class MicropubController extends Controller
{
try {
$tokenData = $this->tokenService->validateToken($request->bearerToken());
- } catch (\Exception $e) {
+ } catch (InvalidTokenException $e) {
return response()->json([
'response' => 'error',
'error' => 'invalid_token',
@@ -57,106 +58,203 @@ class MicropubController extends Controller
], 400);
}
if ($tokenData->hasClaim('scope')) {
- $scopes = explode(' ', $tokenData->getClaim('scope'));
- if (array_search('create', $scopes) !== false) {
- $clientId = $tokenData->getClaim('client_id');
- if (($request->input('h') == 'entry') || ($request->input('type')[0] == 'h-entry')) {
- $data = [];
- $data['client-id'] = $clientId;
- if ($request->header('Content-Type') == 'application/json') {
- $data['content'] = $request->input('properties.content')[0];
- $data['in-reply-to'] = $request->input('properties.in-reply-to')[0];
- $data['location'] = $request->input('properties.location');
- //flatten location if array
- if (is_array($data['location'])) {
- $data['location'] = $data['location'][0];
- }
- } else {
- $data['content'] = $request->input('content');
- $data['in-reply-to'] = $request->input('in-reply-to');
- $data['location'] = $request->input('location');
- }
- $data['syndicate'] = [];
- $targets = array_pluck(config('syndication.targets'), 'uid', 'service.name');
- if (is_string($request->input('mp-syndicate-to'))) {
- $service = array_search($request->input('mp-syndicate-to'));
- if ($service == 'Twitter') {
- $data['syndicate'][] = 'twitter';
- }
- if ($service == 'Facebook') {
- $data['syndicate'][] = 'facebook';
- }
- }
- if (is_array($request->input('mp-syndicate-to'))) {
- foreach ($targets as $service => $target) {
- if (in_array($target, $request->input('mp-syndicate-to'))) {
- if ($service == 'Twitter') {
- $data['syndicate'][] = 'twitter';
- }
- if ($service == 'Facebook') {
- $data['syndicate'][] = 'facebook';
- }
- }
- }
- }
- $data['photo'] = [];
- if (is_array($request->input('photo'))) {
- foreach ($request->input('photo') as $photo) {
- if (is_string($photo)) {
- //only supporting media URLs for now
- $data['photo'][] = $photo;
- }
- }
- }
- try {
- $note = $this->noteService->createNote($data);
- } catch (Exception $exception) {
- return response()->json(['error' => true], 400);
- }
-
- return response()->json([
- 'response' => 'created',
- 'location' => $note->longurl,
- ], 201)->header('Location', $note->longurl);
+ if (($request->input('h') == 'entry') || ($request->input('type')[0] == 'h-entry')) {
+ if (stristr($tokenData->getClaim('scope'), 'create') === false) {
+ return $this->returnInsufficientScopeResponse();
}
- if ($request->input('h') == 'card' || $request->input('type')[0] == 'h-card') {
- $data = [];
- if ($request->header('Content-Type') == 'application/json') {
- $data['name'] = $request->input('properties.name');
- $data['description'] = $request->input('properties.description') ?? null;
- if ($request->has('properties.geo')) {
- $data['geo'] = $request->input('properties.geo');
- }
- } else {
- $data['name'] = $request->input('name');
- $data['description'] = $request->input('description');
- if ($request->has('geo')) {
- $data['geo'] = $request->input('geo');
- }
- if ($request->has('latitude')) {
- $data['latitude'] = $request->input('latitude');
- $data['longitude'] = $request->input('longitude');
+ $data = [];
+ $data['client-id'] = $tokenData->getClaim('client_id');
+ if ($request->header('Content-Type') == 'application/json') {
+ if (is_string($request->input('properties.content')[0])) {
+ $data['content'] = $request->input('properties.content')[0]; //plaintext content
+ }
+ if (is_array($request->input('properties.content')[0])
+ && array_key_exists('html', $request->input('properties.content')[0])
+ ) {
+ $data['content'] = $request->input('properties.content')[0]['html'];
+ }
+ $data['in-reply-to'] = $request->input('properties.in-reply-to')[0];
+ $data['location'] = $request->input('properties.location');
+ //flatten location if array
+ if (is_array($data['location'])) {
+ $data['location'] = $data['location'][0];
+ }
+ $data['published'] = $request->input('properties.published')[0];
+ //create checkin place
+ if (array_key_exists('checkin', $request->input('properties'))) {
+ $data['checkin'] = $request->input('properties.checkin.0.properties.url.0');
+ try {
+ $this->placeService->createPlaceFromCheckin($request->input('properties.checkin.0'));
+ } catch (\Exception $e) {
+ $data['checkin'] = null;
}
}
- try {
- $place = $this->placeService->createPlace($data);
- } catch (Exception $exception) {
- return response()->json(['error' => true], 400);
+ } else {
+ $data['content'] = $request->input('content');
+ $data['in-reply-to'] = $request->input('in-reply-to');
+ $data['location'] = $request->input('location');
+ $data['published'] = $request->input('published');
+ }
+ $data['syndicate'] = [];
+ $targets = array_pluck(config('syndication.targets'), 'uid', 'service.name');
+ if (is_string($request->input('mp-syndicate-to'))) {
+ $service = array_search($request->input('mp-syndicate-to'));
+ if ($service == 'Twitter') {
+ $data['syndicate'][] = 'twitter';
}
+ if ($service == 'Facebook') {
+ $data['syndicate'][] = 'facebook';
+ }
+ }
+ if (is_array($request->input('mp-syndicate-to'))) {
+ foreach ($targets as $service => $target) {
+ if (in_array($target, $request->input('mp-syndicate-to'))) {
+ if ($service == 'Twitter') {
+ $data['syndicate'][] = 'twitter';
+ }
+ if ($service == 'Facebook') {
+ $data['syndicate'][] = 'facebook';
+ }
+ }
+ }
+ }
+ $data['photo'] = [];
+ if (is_array($request->input('photo'))) {
+ foreach ($request->input('photo') as $photo) {
+ if (is_string($photo)) {
+ //only supporting media URLs for now
+ $data['photo'][] = $photo;
+ }
+ }
+ }
+ try {
+ $note = $this->noteService->createNote($data);
+ } catch (\Exception $exception) {
+ return response()->json(['error' => true], 400);
+ }
- return response()->json([
- 'response' => 'created',
- 'location' => $place->longurl,
- ], 201)->header('Location', $place->longurl);
+ return response()->json([
+ 'response' => 'created',
+ 'location' => $note->longurl,
+ ], 201)->header('Location', $note->longurl);
+ }
+ if ($request->input('h') == 'card' || $request->input('type')[0] == 'h-card') {
+ if (stristr($tokenData->getClaim('scope'), 'create') === false) {
+ return $this->returnInsufficientScopeResponse();
+ }
+ $data = [];
+ if ($request->header('Content-Type') == 'application/json') {
+ $data['name'] = $request->input('properties.name');
+ $data['description'] = $request->input('properties.description') ?? null;
+ if ($request->has('properties.geo')) {
+ $data['geo'] = $request->input('properties.geo');
+ }
+ } else {
+ $data['name'] = $request->input('name');
+ $data['description'] = $request->input('description');
+ if ($request->has('geo')) {
+ $data['geo'] = $request->input('geo');
+ }
+ if ($request->has('latitude')) {
+ $data['latitude'] = $request->input('latitude');
+ $data['longitude'] = $request->input('longitude');
+ }
+ }
+ try {
+ $place = $this->placeService->createPlace($data);
+ } catch (\Exception $exception) {
+ return response()->json(['error' => true], 400);
+ }
+
+ return response()->json([
+ 'response' => 'created',
+ 'location' => $place->longurl,
+ ], 201)->header('Location', $place->longurl);
+ }
+ if ($request->input('action') == 'update') {
+ if (stristr($tokenData->getClaim('scope'), 'update') === false) {
+ return $this->returnInsufficientScopeResponse();
+ }
+ $urlPath = parse_url($request->input('url'), PHP_URL_PATH);
+ //is it a note we are updating?
+ if (mb_substr($urlPath, 1, 5) === 'notes') {
+ try {
+ $note = Note::nb60(basename($urlPath))->first();
+ } catch (\Exception $exception) {
+ return response()->json([
+ 'error' => 'invalid_request',
+ 'error_description' => 'No known note with given ID',
+ ]);
+ }
+ //got the note, are we dealing with a “replace” request?
+ if ($request->has('replace')) {
+ foreach ($request->input('replace') as $property => $value) {
+ if ($property == 'content') {
+ $note->note = $value[0];
+ }
+ if ($property == 'syndication') {
+ foreach ($value as $syndicationURL) {
+ if (starts_with($syndicationURL, 'https://www.facebook.com')) {
+ $note->facebook_url = $syndicationURL;
+ }
+ if (starts_with($syndicationURL, 'https://www.swarmapp.com')) {
+ $note->swarm_url = $syndicationURL;
+ }
+ if (starts_with($syndicationURL, 'https://twitter.com')) {
+ $note->tweet_id = basename(parse_url($syndicationURL, PHP_URL_PATH));
+ }
+ }
+ }
+ }
+ $note->save();
+
+ return response()->json([
+ 'response' => 'updated',
+ ]);
+ }
+ //how about “add”
+ if ($request->has('add')) {
+ foreach ($request->input('add') as $property => $value) {
+ if ($property == 'syndication') {
+ foreach ($value as $syndicationURL) {
+ if (starts_with($syndicationURL, 'https://www.facebook.com')) {
+ $note->facebook_url = $syndicationURL;
+ }
+ if (starts_with($syndicationURL, 'https://www.swarmapp.com')) {
+ $note->swarm_url = $syndicationURL;
+ }
+ if (starts_with($syndicationURL, 'https://twitter.com')) {
+ $note->tweet_id = basename(parse_url($syndicationURL, PHP_URL_PATH));
+ }
+ }
+ }
+ if ($property == 'photo') {
+ foreach ($value as $photoURL) {
+ if (start_with($photo, 'https://')) {
+ $media = new Media();
+ $media->path = $photoURL;
+ $media->type = 'image';
+ $media->save();
+ $note->media()->save($media);
+ }
+ }
+ }
+ }
+ $note->save();
+
+ return response()->json([
+ 'response' => 'updated',
+ ]);
+ }
}
}
}
return response()->json([
'response' => 'error',
- 'error' => 'invalid_token',
- 'error_description' => 'The token provided is not valid or does not have the necessary scope',
- ], 400);
+ 'error' => 'forbidden',
+ 'error_description' => 'The token has no scopes',
+ ], 403);
}
/**
@@ -172,7 +270,7 @@ class MicropubController extends Controller
{
try {
$tokenData = $this->tokenService->validateToken($request->bearerToken());
- } catch (\Exception $e) {
+ } catch (InvalidTokenException $e) {
return response()->json([
'response' => 'error',
'error' => 'invalid_token',
@@ -232,8 +330,9 @@ class MicropubController extends Controller
*/
public function media(Request $request)
{
- $tokenData = $this->tokenService->validateToken($request->bearerToken());
- if ($tokenData === null) {
+ try {
+ $tokenData = $this->tokenService->validateToken($request->bearerToken());
+ } catch (InvalidTokenException $e) {
return response()->json([
'response' => 'error',
'error' => 'invalid_token',
@@ -243,54 +342,54 @@ class MicropubController extends Controller
//check post scope
if ($tokenData->hasClaim('scope')) {
- $scopes = explode(' ', $tokenData->getClaim('scope'));
- if (array_search('post', $scopes) !== false) {
- //check media valid
- if ($request->hasFile('file') && $request->file('file')->isValid()) {
- $type = $this->getFileTypeFromMimeType($request->file('file')->getMimeType());
- try {
- $filename = Uuid::uuid4() . '.' . $request->file('file')->extension();
- } catch (UnsatisfiedDependencyException $e) {
- return response()->json([
- 'response' => 'error',
- 'error' => 'internal_server_error',
- 'error_description' => 'A problem occured handling your request',
- ], 500);
- }
- try {
- $path = $request->file('file')->storeAs('media', $filename, 's3');
- } catch (Exception $e) { // which exception?
- return response()->json([
- 'response' => 'error',
- 'error' => 'service_unavailable',
- 'error_description' => 'Unable to save media to S3',
- ], 503);
- }
- $media = new Media();
- $media->token = $request->bearerToken();
- $media->path = $path;
- $media->type = $type;
- $media->save();
-
+ if (stristr($token->getClaim('scope'), 'post') === false) {
+ return $this->returnInsufficientScopeResponse();
+ }
+ //check media valid
+ if ($request->hasFile('file') && $request->file('file')->isValid()) {
+ $type = $this->getFileTypeFromMimeType($request->file('file')->getMimeType());
+ try {
+ $filename = Uuid::uuid4() . '.' . $request->file('file')->extension();
+ } catch (UnsatisfiedDependencyException $e) {
return response()->json([
- 'response' => 'created',
- 'location' => $media->url,
- ], 201)->header('Location', $media->url);
+ 'response' => 'error',
+ 'error' => 'internal_server_error',
+ 'error_description' => 'A problem occured handling your request',
+ ], 500);
}
+ try {
+ $path = $request->file('file')->storeAs('media', $filename, 's3');
+ } catch (Exception $e) { // which exception?
+ return response()->json([
+ 'response' => 'error',
+ 'error' => 'service_unavailable',
+ 'error_description' => 'Unable to save media to S3',
+ ], 503);
+ }
+ $media = new Media();
+ $media->token = $request->bearerToken();
+ $media->path = $path;
+ $media->type = $type;
+ $media->save();
return response()->json([
- 'response' => 'error',
- 'error' => 'invalid_request',
- 'error_description' => 'The uploaded file failed validation',
- ], 400);
+ 'response' => 'created',
+ 'location' => $media->url,
+ ], 201)->header('Location', $media->url);
}
+
+ return response()->json([
+ 'response' => 'error',
+ 'error' => 'invalid_request',
+ 'error_description' => 'The uploaded file failed validation',
+ ], 400);
}
return response()->json([
'response' => 'error',
- 'error' => 'insufficient_scope',
- 'error_description' => 'The provided token has insufficient scopes',
- ], 401);
+ 'error' => 'invalid_request',
+ 'error_description' => 'The provided token has no scopes',
+ ], 400);
}
/**
@@ -336,4 +435,13 @@ class MicropubController extends Controller
return 'download';
}
+
+ private function returnInsufficientScopeResponse()
+ {
+ return response()->json([
+ 'response' => 'error',
+ 'error' => 'insufficient_scope',
+ 'error_description' => 'The token’s scope does not have the necessary requirements.',
+ ], 401);
+ }
}
diff --git a/app/Http/Controllers/TokenEndpointController.php b/app/Http/Controllers/TokenEndpointController.php
new file mode 100644
index 00000000..fb0da5ac
--- /dev/null
+++ b/app/Http/Controllers/TokenEndpointController.php
@@ -0,0 +1,79 @@
+client = $client ?? new Client();
+ $this->tokenService = $tokenService ?? new TokenService();
+ }
+
+ /**
+ * If the user has auth’d via the IndieAuth protocol, issue a valid token.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\Http\Response
+ */
+ public function create(Request $request)
+ {
+ $authorizationEndpoint = $this->client->discoverAuthorizationEndpoint(normalize_url($request->input('me')));
+ if ($authorizationEndpoint) {
+ $auth = $this->client->verifyIndieAuthCode(
+ $authorizationEndpoint,
+ $request->input('code'),
+ $request->input('me'),
+ $request->input('redirect_uri'),
+ $request->input('client_id'),
+ $request->input('state')
+ );
+ if (array_key_exists('me', $auth)) {
+ $scope = $auth['scope'] ?? '';
+ $tokenData = [
+ 'me' => $request->input('me'),
+ 'client_id' => $request->input('client_id'),
+ 'scope' => $scope,
+ ];
+ $token = $this->tokenService->getNewToken($tokenData);
+ $content = http_build_query([
+ 'me' => $request->input('me'),
+ 'scope' => $scope,
+ 'access_token' => $token,
+ ]);
+
+ return response($content)->header(
+ 'Content-Type',
+ 'application/x-www-form-urlencoded'
+ );
+ }
+
+ return response('There was an error verifying the authorisation code.', 400);
+ }
+
+ return response('Can’t determine the authorisation endpoint.', 400);
+ }
+}
diff --git a/app/Media.php b/app/Media.php
index f0234c6e..bf329391 100644
--- a/app/Media.php
+++ b/app/Media.php
@@ -28,6 +28,10 @@ class Media extends Model
*/
public function getUrlAttribute()
{
+ if (starts_with($this->path, 'https://')) {
+ return $this->path;
+ }
+
return config('filesystems.disks.s3.url') . '/' . $this->path;
}
}
diff --git a/app/Note.php b/app/Note.php
index 6a51a896..000ccd25 100644
--- a/app/Note.php
+++ b/app/Note.php
@@ -191,6 +191,20 @@ class Note extends Model
return $name;
}
+ /**
+ * Scope a query to select a note via a NewBase60 id.
+ *
+ * @param \Illuminate\Database\Eloquent\Builder $query
+ * @param string $nb60id
+ * @return \Illuminate\Database\Eloquent\Builder
+ */
+ public function scopeNb60($query, $nb60id)
+ {
+ $numbers = new Numbers();
+
+ return $query->where('id', $numbers->b60tonum($nb60id));
+ }
+
/**
* Take note that this method does two things, given @username (NOT [@username](URL)!)
* we try to create a fancy hcard from our contact info. If this is not possible
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index d3aa0488..88d47aec 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -33,7 +33,7 @@ class AppServiceProvider extends ServiceProvider
//Add tags for notes
Note::created(function ($note) {
$tagsToAdd = [];
- preg_match_all('/#([^\s<>]+)\b/', $note, $tags);
+ preg_match_all('/#([^\s<>]+)\b/', $note->note, $tags);
foreach ($tags[1] as $tag) {
$tag = Tag::normalizeTag($tag);
}
diff --git a/app/Services/NoteService.php b/app/Services/NoteService.php
index d395327b..09dbb1c9 100644
--- a/app/Services/NoteService.php
+++ b/app/Services/NoteService.php
@@ -17,6 +17,16 @@ class NoteService
*/
public function createNote(array $data): Note
{
+ //check the input
+ if (array_key_exists('content', $data) === false) {
+ throw new \Exception('No content defined'); //we can’t fudge the data
+ }
+ if (array_key_exists('in-reply-to', $data) === false) {
+ $data['in-reply-to'] = null;
+ }
+ if (array_key_exists('client-id', $data) === false) {
+ $data['client-id'] = null;
+ }
$note = Note::create(
[
'note' => $data['content'],
@@ -25,6 +35,11 @@ class NoteService
]
);
+ if (array_key_exists('published', $data) && empty($data['published']) === false) {
+ $carbon = new \Carbon\Carbon($data['published']);
+ $note->created_at = $note->updated_at = $carbon->toDateTimeString();
+ }
+
if (array_key_exists('location', $data) && $data['location'] !== null && $data['location'] !== 'no-location') {
if (starts_with($data['location'], config('app.url'))) {
//uri of form http://host/places/slug, we want slug
@@ -44,6 +59,13 @@ class NoteService
}
}
+ if (array_key_exists('checkin', $data) && $data['checkin'] !== null) {
+ $place = Place::where('foursquare', $data['checkin'])->first();
+ if ($place !== null) {
+ $note->place()->associate($place);
+ }
+ }
+
/* drop image support for now
//add images to media library
if ($request->hasFile('photo')) {
@@ -55,12 +77,17 @@ class NoteService
*/
//add support for media uploaded as URLs
foreach ($data['photo'] as $photo) {
- // check the media was uploaded to my endpoint
+ // check the media was uploaded to my endpoint, and use path
if (starts_with($photo, config('filesystems.disks.s3.url'))) {
$path = substr($photo, strlen(config('filesystems.disks.s3.url')));
$media = Media::where('path', ltrim($path, '/'))->firstOrFail();
- $note->media()->save($media);
+ } else {
+ $media = Media::firstOrNew(['path' => $photo]);
+ // currently assuming this is a photo from Swarm
+ $media->type = 'image';
+ $media->save();
}
+ $note->media()->save($media);
}
$note->save();
diff --git a/app/Services/PlaceService.php b/app/Services/PlaceService.php
index 1a02dff5..f1bc249a 100644
--- a/app/Services/PlaceService.php
+++ b/app/Services/PlaceService.php
@@ -36,4 +36,39 @@ class PlaceService
return $place;
}
+
+ /**
+ * Create a place from a h-card checkin, for exameple from OwnYourSwarm.
+ *
+ * @param array
+ * @return bool
+ */
+ public function createPlaceFromCheckin(array $checkin): bool
+ {
+ //check if the place exists if from swarm
+ if (array_key_exists('url', $checkin['properties'])) {
+ $search = Place::where('foursquare', $checkin['properties']['url'][0])->count();
+ if ($search === 1) {
+ return true;
+ }
+ }
+ if (array_key_exists('name', $checkin['properties']) === false) {
+ throw new \InvalidArgumentException('Missing required name');
+ }
+ if (array_key_exists('latitude', $checkin['properties']) === false) {
+ throw new \InvalidArgumentException('Missing required longitude/latitude');
+ }
+ $place = new Place();
+ $place->name = $checkin['properties']['name'][0];
+ if (starts_with($checkin['properties']['url'][0], 'https://foursquare.com')) {
+ $place->foursquare = $checkin['properties']['url'][0];
+ }
+ $place->location = new Point(
+ (float) $checkin['properties']['latitude'][0],
+ (float) $checkin['properties']['longitude'][0]
+ );
+ $place->save();
+
+ return true;
+ }
}
diff --git a/app/Services/TokenService.php b/app/Services/TokenService.php
index fecb8ded..42f2f718 100644
--- a/app/Services/TokenService.php
+++ b/app/Services/TokenService.php
@@ -4,10 +4,9 @@ declare(strict_types=1);
namespace App\Services;
-use Lcobucci\JWT\Token;
-use Lcobucci\JWT\Parser;
-use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Hmac\Sha256;
+use App\Exceptions\InvalidTokenException;
+use Lcobucci\JWT\{Builder, Parser, Token};
class TokenService
{
@@ -40,9 +39,13 @@ class TokenService
public function validateToken(string $bearerToken): ?Token
{
$signer = new Sha256();
- $token = (new Parser())->parse((string) $bearerToken);
+ try {
+ $token = (new Parser())->parse((string) $bearerToken);
+ } catch (\InvalidArgumentException $e) {
+ throw new InvalidTokenException('Token could not be parsed');
+ }
if (! $token->verify($signer, config('app.key'))) {
- throw new \Exception('Token not verified');
+ throw new InvalidTokenException('Token failed verification');
}
return $token;
diff --git a/app/helpers.php b/app/helpers.php
deleted file mode 100644
index 6dcad34d..00000000
--- a/app/helpers.php
+++ /dev/null
@@ -1,191 +0,0 @@
- 80, 'https' => 443];
- if (isset($url['scheme'])) {
- $url['scheme'] = strtolower($url['scheme']);
- // Strip scheme default ports
- if (
- isset($defaultSchemes[$url['scheme']]) &&
- isset($url['port']) &&
- $defaultSchemes[$url['scheme']] == $url['port']
- ) {
- unset($url['port']);
- }
- $newUrl .= "{$url['scheme']}://";
- }
- if (isset($url['host'])) {
- $url['host'] = mb_strtolower($url['host']);
- $newUrl .= $url['host'];
- }
- if (isset($url['port'])) {
- $newUrl .= ":{$url['port']}";
- }
- // here we only want to drop a slash for the root domain
- // e.g. http://example.com/ -> http://example.com
- // but http://example.com/path/ -/-> http://example.com/path
- if (isset($url['path']) && $url['path'] == '/') {
- unset($url['path']);
- }
- if (isset($url['path'])) {
- // Case normalization
- $url['path'] = normalizer_normalize($url['path'], Normalizer::FORM_C);
- // Strip duplicate slashes
- while (preg_match("/\/\//", $url['path'])) {
- $url['path'] = preg_replace('/\/\//', '/', $url['path']);
- }
-
- /*
- * Decode unreserved characters, http://www.apps.ietf.org/rfc/rfc3986.html#sec-2.3
- * Heavily rewritten version of urlDecodeUnreservedChars() in Glen Scott's url-normalizer.
- */
- $u = [];
- for ($o = 65; $o <= 90; $o++) {
- $u[] = dechex($o);
- }
- for ($o = 97; $o <= 122; $o++) {
- $u[] = dechex($o);
- }
- for ($o = 48; $o <= 57; $o++) {
- $u[] = dechex($o);
- }
- $chrs = ['-', '.', '_', '~'];
- foreach ($chrs as $chr) {
- $u[] = dechex(ord($chr));
- }
- $url['path'] = preg_replace_callback(
- array_map(
- create_function('$str', 'return "/%" . strtoupper($str) . "/x";'),
- $u
- ),
- create_function('$matches', 'return chr(hexdec($matches[0]));'),
- $url['path']
- );
- // Remove directory index
- $defaultIndexes = ["/default\.aspx/" => 'default.aspx', "/default\.asp/" => 'default.asp',
- "/index\.html/" => 'index.html', "/index\.htm/" => 'index.htm',
- "/default\.html/" => 'default.html', "/default\.htm/" => 'default.htm',
- "/index\.php/" => 'index.php', "/index\.jsp/" => 'index.jsp', ];
- foreach ($defaultIndexes as $index => $strip) {
- if (preg_match($index, $url['path'])) {
- $url['path'] = str_replace($strip, '', $url['path']);
- }
- }
-
- /**
- * Path segment normalization, http://www.apps.ietf.org/rfc/rfc3986.html#sec-5.2.4
- * Heavily rewritten version of removeDotSegments() in Glen Scott's url-normalizer.
- */
- $new_path = '';
- while (! empty($url['path'])) {
- if (preg_match('!^(\.\./|\./)!x', $url['path'])) {
- $url['path'] = preg_replace('!^(\.\./|\./)!x', '', $url['path']);
- } elseif (preg_match('!^(/\./)!x', $url['path'], $matches) || preg_match('!^(/\.)$!x', $url['path'], $matches)) {
- $url['path'] = preg_replace('!^' . $matches[1] . '!', '/', $url['path']);
- } elseif (preg_match('!^(/\.\./|/\.\.)!x', $url['path'], $matches)) {
- $url['path'] = preg_replace('!^' . preg_quote($matches[1], '!') . '!x', '/', $url['path']);
- $new_path = preg_replace('!/([^/]+)$!x', '', $new_path);
- } elseif (preg_match('!^(\.|\.\.)$!x', $url['path'])) {
- $url['path'] = preg_replace('!^(\.|\.\.)$!x', '', $url['path']);
- } else {
- if (preg_match('!(/*[^/]*)!x', $url['path'], $matches)) {
- $first_path_segment = $matches[1];
- $url['path'] = preg_replace('/^' . preg_quote($first_path_segment, '/') . '/', '', $url['path'], 1);
- $new_path .= $first_path_segment;
- }
- }
- }
- $newUrl .= $new_path;
- }
-
- if (isset($url['fragment'])) {
- unset($url['fragment']);
- }
-
- // Sort GET params alphabetically, not because the RFC requires it but because it's cool!
- if (isset($url['query'])) {
- if (preg_match('/&/', $url['query'])) {
- $s = explode('&', $url['query']);
- $url['query'] = '';
- sort($s);
- foreach ($s as $z) {
- $url['query'] .= "{$z}&";
- }
- $url['query'] = preg_replace('/&\Z/', '', $url['query']);
- }
- $newUrl .= "?{$url['query']}";
- }
-
- return $newUrl;
-}
-
-// sourced from https://stackoverflow.com/a/9776726
-function prettyPrintJson(string $json): string
-{
- $result = '';
- $level = 0;
- $in_quotes = false;
- $in_escape = false;
- $ends_line_level = null;
- $json_length = strlen($json);
-
- for ($i = 0; $i < $json_length; $i++) {
- $char = $json[$i];
- $new_line_level = null;
- $post = '';
- if ($ends_line_level !== null) {
- $new_line_level = $ends_line_level;
- $ends_line_level = null;
- }
- if ($in_escape) {
- $in_escape = false;
- } elseif ($char === '"') {
- $in_quotes = ! $in_quotes;
- } elseif (! $in_quotes) {
- switch ($char) {
- case '}': case ']':
- $level--;
- $ends_line_level = null;
- $new_line_level = $level;
- break;
-
- case '{': case '[':
- $level++;
- case ',':
- $ends_line_level = $level;
- break;
-
- case ':':
- $post = ' ';
- break;
-
- case ' ': case "\t": case "\n": case "\r":
- $char = '';
- $ends_line_level = $new_line_level;
- $new_line_level = null;
- break;
- }
- } elseif ($char === '\\') {
- $in_escape = true;
- }
- if ($new_line_level !== null) {
- $result .= "\n".str_repeat("\t", $new_line_level);
- }
- $result .= $char.$post;
- }
-
- return str_replace("\t", ' ', $result);
-}
diff --git a/composer.json b/composer.json
index b5531f9a..d1ff9e16 100644
--- a/composer.json
+++ b/composer.json
@@ -44,7 +44,7 @@
"App\\": "app/"
},
"files": [
- "app/helpers.php"
+ "helpers.php"
]
},
"autoload-dev": {
diff --git a/composer.lock b/composer.lock
index 2188bc12..02b615a3 100644
--- a/composer.lock
+++ b/composer.lock
@@ -8,16 +8,16 @@
"packages": [
{
"name": "aws/aws-sdk-php",
- "version": "3.25.7",
+ "version": "3.27.2",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
- "reference": "d4f1104f5ac9c755875c5e6e9bade2c70708219a"
+ "reference": "eb10e43cccf8e868f9622ab8ce2beb9fb756b5a8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d4f1104f5ac9c755875c5e6e9bade2c70708219a",
- "reference": "d4f1104f5ac9c755875c5e6e9bade2c70708219a",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/eb10e43cccf8e868f9622ab8ce2beb9fb756b5a8",
+ "reference": "eb10e43cccf8e868f9622ab8ce2beb9fb756b5a8",
"shasum": ""
},
"require": {
@@ -39,7 +39,7 @@
"ext-simplexml": "*",
"ext-spl": "*",
"nette/neon": "^2.3",
- "phpunit/phpunit": "~4.0|~5.0",
+ "phpunit/phpunit": "^4.8.35|^5.4.0",
"psr/cache": "^1.0"
},
"suggest": {
@@ -84,7 +84,7 @@
"s3",
"sdk"
],
- "time": "2017-04-11T22:31:27+00:00"
+ "time": "2017-05-11T21:23:43+00:00"
},
{
"name": "barnabywalters/mf-cleaner",
@@ -1104,16 +1104,16 @@
},
{
"name": "indieauth/client",
- "version": "0.2.0",
+ "version": "0.2.1",
"source": {
"type": "git",
"url": "https://github.com/indieweb/indieauth-client-php.git",
- "reference": "4b9bd766a92b8abbe420f5889bf7ebac7678151d"
+ "reference": "f5f6efad79334d1ff9370fe4dce8ccf4814820fa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/indieweb/indieauth-client-php/zipball/4b9bd766a92b8abbe420f5889bf7ebac7678151d",
- "reference": "4b9bd766a92b8abbe420f5889bf7ebac7678151d",
+ "url": "https://api.github.com/repos/indieweb/indieauth-client-php/zipball/f5f6efad79334d1ff9370fe4dce8ccf4814820fa",
+ "reference": "f5f6efad79334d1ff9370fe4dce8ccf4814820fa",
"shasum": ""
},
"require": {
@@ -1139,7 +1139,7 @@
}
],
"description": "IndieAuth Client Library",
- "time": "2017-02-09T23:42:05+00:00"
+ "time": "2017-04-26T21:44:35+00:00"
},
{
"name": "indieweb/link-rel-parser",
@@ -1464,16 +1464,16 @@
},
{
"name": "laravel/framework",
- "version": "v5.4.19",
+ "version": "v5.4.23",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "02444b7450350db17a7607c8a52f7268ebdb0dad"
+ "reference": "ad82327705658dbf5f0ce72805caa950dfbe150d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/02444b7450350db17a7607c8a52f7268ebdb0dad",
- "reference": "02444b7450350db17a7607c8a52f7268ebdb0dad",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/ad82327705658dbf5f0ce72805caa950dfbe150d",
+ "reference": "ad82327705658dbf5f0ce72805caa950dfbe150d",
"shasum": ""
},
"require": {
@@ -1589,7 +1589,7 @@
"framework",
"laravel"
],
- "time": "2017-04-16T13:33:34+00:00"
+ "time": "2017-05-11T20:10:35+00:00"
},
{
"name": "laravel/scout",
@@ -1769,16 +1769,16 @@
},
{
"name": "league/commonmark",
- "version": "0.15.3",
+ "version": "0.15.4",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
- "reference": "c8b43ee5821362216f8e9ac684f0f59de164edcc"
+ "reference": "c4c8e6bf99e62d9568875d9fc3ef473fe3e18e0c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c8b43ee5821362216f8e9ac684f0f59de164edcc",
- "reference": "c8b43ee5821362216f8e9ac684f0f59de164edcc",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c4c8e6bf99e62d9568875d9fc3ef473fe3e18e0c",
+ "reference": "c4c8e6bf99e62d9568875d9fc3ef473fe3e18e0c",
"shasum": ""
},
"require": {
@@ -1834,20 +1834,20 @@
"markdown",
"parser"
],
- "time": "2016-12-19T00:11:43+00:00"
+ "time": "2017-05-09T12:47:53+00:00"
},
{
"name": "league/flysystem",
- "version": "1.0.37",
+ "version": "1.0.40",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "78b5cc4feb61a882302df4fbaf63b7662e5e4ccd"
+ "reference": "3828f0b24e2c1918bb362d57a53205d6dc8fde61"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/78b5cc4feb61a882302df4fbaf63b7662e5e4ccd",
- "reference": "78b5cc4feb61a882302df4fbaf63b7662e5e4ccd",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3828f0b24e2c1918bb362d57a53205d6dc8fde61",
+ "reference": "3828f0b24e2c1918bb362d57a53205d6dc8fde61",
"shasum": ""
},
"require": {
@@ -1869,12 +1869,12 @@
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"league/flysystem-copy": "Allows you to use Copy.com storage",
- "league/flysystem-dropbox": "Allows you to use Dropbox storage",
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
- "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter"
+ "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
+ "spatie/flysystem-dropbox": "Allows you to use Dropbox storage"
},
"type": "library",
"extra": {
@@ -1917,25 +1917,25 @@
"sftp",
"storage"
],
- "time": "2017-03-22T15:43:14+00:00"
+ "time": "2017-04-28T10:15:08+00:00"
},
{
"name": "league/flysystem-aws-s3-v3",
- "version": "1.0.13",
+ "version": "1.0.15",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
- "reference": "dc56a8faf3aff0841f9eae04b6af94a50657896c"
+ "reference": "c947f36f977b495a57e857ae1630df0da35ec456"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/dc56a8faf3aff0841f9eae04b6af94a50657896c",
- "reference": "dc56a8faf3aff0841f9eae04b6af94a50657896c",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/c947f36f977b495a57e857ae1630df0da35ec456",
+ "reference": "c947f36f977b495a57e857ae1630df0da35ec456",
"shasum": ""
},
"require": {
"aws/aws-sdk-php": "^3.0.0",
- "league/flysystem": "~1.0",
+ "league/flysystem": "^1.0.40",
"php": ">=5.5.0"
},
"require-dev": {
@@ -1964,7 +1964,7 @@
}
],
"description": "Flysystem adapter for the AWS S3 SDK v3.x",
- "time": "2016-06-21T21:34:35+00:00"
+ "time": "2017-04-28T10:21:54+00:00"
},
{
"name": "martinbean/laravel-sluggable-trait",
@@ -2844,16 +2844,16 @@
},
{
"name": "swiftmailer/swiftmailer",
- "version": "v5.4.6",
+ "version": "v5.4.8",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
- "reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e"
+ "reference": "9a06dc570a0367850280eefd3f1dc2da45aef517"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e",
- "reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e",
+ "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/9a06dc570a0367850280eefd3f1dc2da45aef517",
+ "reference": "9a06dc570a0367850280eefd3f1dc2da45aef517",
"shasum": ""
},
"require": {
@@ -2894,20 +2894,20 @@
"mail",
"mailer"
],
- "time": "2017-02-13T07:52:53+00:00"
+ "time": "2017-05-01T15:54:03+00:00"
},
{
"name": "symfony/console",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "c30243cc51f726812be3551316b109a2f5deaf8d"
+ "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/c30243cc51f726812be3551316b109a2f5deaf8d",
- "reference": "c30243cc51f726812be3551316b109a2f5deaf8d",
+ "url": "https://api.github.com/repos/symfony/console/zipball/a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38",
+ "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38",
"shasum": ""
},
"require": {
@@ -2957,20 +2957,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2017-04-04T14:33:42+00:00"
+ "time": "2017-04-26T01:39:17+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c"
+ "reference": "02983c144038e697c959e6b06ef6666de759ccbc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/a48f13dc83c168f1253a5d2a5a4fb46c36244c4c",
- "reference": "a48f13dc83c168f1253a5d2a5a4fb46c36244c4c",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/02983c144038e697c959e6b06ef6666de759ccbc",
+ "reference": "02983c144038e697c959e6b06ef6666de759ccbc",
"shasum": ""
},
"require": {
@@ -3010,20 +3010,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2017-02-21T09:12:04+00:00"
+ "time": "2017-05-01T14:55:58+00:00"
},
{
"name": "symfony/debug",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "56f613406446a4a0a031475cfd0a01751de22659"
+ "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/56f613406446a4a0a031475cfd0a01751de22659",
- "reference": "56f613406446a4a0a031475cfd0a01751de22659",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/fd6eeee656a5a7b384d56f1072243fe1c0e81686",
+ "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686",
"shasum": ""
},
"require": {
@@ -3067,20 +3067,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2017-03-28T21:38:24+00:00"
+ "time": "2017-04-19T20:17:50+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "154bb1ef7b0e42ccc792bd53edbce18ed73440ca"
+ "reference": "b8a401f733b43251e1d088c589368b2a94155e40"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/154bb1ef7b0e42ccc792bd53edbce18ed73440ca",
- "reference": "154bb1ef7b0e42ccc792bd53edbce18ed73440ca",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b8a401f733b43251e1d088c589368b2a94155e40",
+ "reference": "b8a401f733b43251e1d088c589368b2a94155e40",
"shasum": ""
},
"require": {
@@ -3127,20 +3127,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2017-04-04T07:26:27+00:00"
+ "time": "2017-05-01T14:58:48+00:00"
},
{
"name": "symfony/finder",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "b20900ce5ea164cd9314af52725b0bb5a758217a"
+ "reference": "9cf076f8f492f4b1ffac40aae9c2d287b4ca6930"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/b20900ce5ea164cd9314af52725b0bb5a758217a",
- "reference": "b20900ce5ea164cd9314af52725b0bb5a758217a",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/9cf076f8f492f4b1ffac40aae9c2d287b4ca6930",
+ "reference": "9cf076f8f492f4b1ffac40aae9c2d287b4ca6930",
"shasum": ""
},
"require": {
@@ -3176,20 +3176,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2017-03-20T09:32:19+00:00"
+ "time": "2017-04-12T14:13:17+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "cb0b6418f588952c9290b3df4ca650f1b7ab570a"
+ "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cb0b6418f588952c9290b3df4ca650f1b7ab570a",
- "reference": "cb0b6418f588952c9290b3df4ca650f1b7ab570a",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9de6add7f731e5af7f5b2e9c0da365e43383ebef",
+ "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef",
"shasum": ""
},
"require": {
@@ -3229,20 +3229,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2017-04-04T15:30:56+00:00"
+ "time": "2017-05-01T14:55:58+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "8285ab5faf1306b1a5ebcf287fe91c231a6de88e"
+ "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8285ab5faf1306b1a5ebcf287fe91c231a6de88e",
- "reference": "8285ab5faf1306b1a5ebcf287fe91c231a6de88e",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/46e8b209abab55c072c47d72d5cd1d62c0585e05",
+ "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05",
"shasum": ""
},
"require": {
@@ -3311,7 +3311,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2017-04-05T12:52:03+00:00"
+ "time": "2017-05-01T17:46:48+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@@ -3374,16 +3374,16 @@
},
{
"name": "symfony/process",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282"
+ "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/57fdaa55827ae14d617550ebe71a820f0a5e2282",
- "reference": "57fdaa55827ae14d617550ebe71a820f0a5e2282",
+ "url": "https://api.github.com/repos/symfony/process/zipball/999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
+ "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
"shasum": ""
},
"require": {
@@ -3419,20 +3419,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2017-03-27T18:07:02+00:00"
+ "time": "2017-04-12T14:13:17+00:00"
},
{
"name": "symfony/routing",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "d6605f9a5767bc5bc4895e1c762ba93964608aee"
+ "reference": "5029745d6d463585e8b487dbc83d6333f408853a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/d6605f9a5767bc5bc4895e1c762ba93964608aee",
- "reference": "d6605f9a5767bc5bc4895e1c762ba93964608aee",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/5029745d6d463585e8b487dbc83d6333f408853a",
+ "reference": "5029745d6d463585e8b487dbc83d6333f408853a",
"shasum": ""
},
"require": {
@@ -3494,20 +3494,20 @@
"uri",
"url"
],
- "time": "2017-03-02T15:58:09+00:00"
+ "time": "2017-04-12T14:13:17+00:00"
},
{
"name": "symfony/translation",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "c740eee70783d2af4d3d6b70d5146f209e6b4d13"
+ "reference": "f4a04d2df710f81515df576b2de06bdeee518b83"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/c740eee70783d2af4d3d6b70d5146f209e6b4d13",
- "reference": "c740eee70783d2af4d3d6b70d5146f209e6b4d13",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/f4a04d2df710f81515df576b2de06bdeee518b83",
+ "reference": "f4a04d2df710f81515df576b2de06bdeee518b83",
"shasum": ""
},
"require": {
@@ -3558,20 +3558,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
- "time": "2017-03-21T21:44:32+00:00"
+ "time": "2017-04-12T14:13:17+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "81dce20f69a8b40427e1f4e6462178df87cafc03"
+ "reference": "fa47963ac7979ddbd42b2d646d1b056bddbf7bb8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/81dce20f69a8b40427e1f4e6462178df87cafc03",
- "reference": "81dce20f69a8b40427e1f4e6462178df87cafc03",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/fa47963ac7979ddbd42b2d646d1b056bddbf7bb8",
+ "reference": "fa47963ac7979ddbd42b2d646d1b056bddbf7bb8",
"shasum": ""
},
"require": {
@@ -3582,9 +3582,11 @@
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
},
"require-dev": {
+ "ext-iconv": "*",
"twig/twig": "~1.20|~2.0"
},
"suggest": {
+ "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
"ext-symfony_debug": ""
},
"type": "library",
@@ -3624,7 +3626,7 @@
"debug",
"dump"
],
- "time": "2017-03-12T16:07:05+00:00"
+ "time": "2017-05-01T14:55:58+00:00"
},
{
"name": "themattharris/tmhoauth",
@@ -3670,16 +3672,16 @@
},
{
"name": "thujohn/twitter",
- "version": "2.2.2",
+ "version": "2.2.5",
"source": {
"type": "git",
"url": "https://github.com/thujohn/twitter.git",
- "reference": "203d903856212835206675ae9c0504d74b681886"
+ "reference": "ff414bdadba3f1570ca211355e5359ec266552d8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thujohn/twitter/zipball/203d903856212835206675ae9c0504d74b681886",
- "reference": "203d903856212835206675ae9c0504d74b681886",
+ "url": "https://api.github.com/repos/thujohn/twitter/zipball/ff414bdadba3f1570ca211355e5359ec266552d8",
+ "reference": "ff414bdadba3f1570ca211355e5359ec266552d8",
"shasum": ""
},
"require": {
@@ -3710,7 +3712,7 @@
"laravel5",
"twitter"
],
- "time": "2017-01-31T23:37:52+00:00"
+ "time": "2017-04-27T09:00:04+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -3921,16 +3923,16 @@
},
{
"name": "facebook/webdriver",
- "version": "1.4.0",
+ "version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/facebook/php-webdriver.git",
- "reference": "3ea034c056189e11c0ce7985332a9f4b5b2b5db2"
+ "reference": "eadb0b7a7c3e6578185197fd40158b08c3164c83"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/3ea034c056189e11c0ce7985332a9f4b5b2b5db2",
- "reference": "3ea034c056189e11c0ce7985332a9f4b5b2b5db2",
+ "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/eadb0b7a7c3e6578185197fd40158b08c3164c83",
+ "reference": "eadb0b7a7c3e6578185197fd40158b08c3164c83",
"shasum": ""
},
"require": {
@@ -3969,7 +3971,7 @@
"selenium",
"webdriver"
],
- "time": "2017-03-22T10:56:03+00:00"
+ "time": "2017-04-28T14:54:49+00:00"
},
{
"name": "fzaninotto/faker",
@@ -4113,21 +4115,22 @@
},
{
"name": "laravel/dusk",
- "version": "v1.0.12",
+ "version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/dusk.git",
- "reference": "9a150bedc3ae6566d05f0a8d1657c658ce98dcad"
+ "reference": "6b81e97ae1ce384e3d8dbd020b2b9751c1449889"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/dusk/zipball/9a150bedc3ae6566d05f0a8d1657c658ce98dcad",
- "reference": "9a150bedc3ae6566d05f0a8d1657c658ce98dcad",
+ "url": "https://api.github.com/repos/laravel/dusk/zipball/6b81e97ae1ce384e3d8dbd020b2b9751c1449889",
+ "reference": "6b81e97ae1ce384e3d8dbd020b2b9751c1449889",
"shasum": ""
},
"require": {
"facebook/webdriver": "~1.0",
- "illuminate/support": "~5.3",
+ "illuminate/console": "~5.4",
+ "illuminate/support": "~5.4",
"nesbot/carbon": "~1.20",
"php": ">=5.6.4",
"symfony/console": "~3.2",
@@ -4164,7 +4167,7 @@
"testing",
"webdriver"
],
- "time": "2017-04-07T21:47:06+00:00"
+ "time": "2017-04-23T17:13:04+00:00"
},
{
"name": "maximebf/debugbar",
@@ -4232,12 +4235,12 @@
"version": "0.9.9",
"source": {
"type": "git",
- "url": "https://github.com/padraic/mockery.git",
+ "url": "https://github.com/mockery/mockery.git",
"reference": "6fdb61243844dc924071d3404bb23994ea0b6856"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/padraic/mockery/zipball/6fdb61243844dc924071d3404bb23994ea0b6856",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/6fdb61243844dc924071d3404bb23994ea0b6856",
"reference": "6fdb61243844dc924071d3404bb23994ea0b6856",
"shasum": ""
},
@@ -5537,16 +5540,16 @@
},
{
"name": "symfony/yaml",
- "version": "v3.2.7",
+ "version": "v3.2.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621"
+ "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/62b4cdb99d52cb1ff253c465eb1532a80cebb621",
- "reference": "62b4cdb99d52cb1ff253c465eb1532a80cebb621",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/acec26fcf7f3031e094e910b94b002fa53d4e4d6",
+ "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6",
"shasum": ""
},
"require": {
@@ -5588,20 +5591,20 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2017-03-20T09:45:15+00:00"
+ "time": "2017-05-01T14:55:58+00:00"
},
{
"name": "theseer/fdomdocument",
- "version": "1.6.4",
+ "version": "1.6.5",
"source": {
"type": "git",
"url": "https://github.com/theseer/fDOMDocument.git",
- "reference": "cf219ede922fb47956726f35e2127277ebd302ca"
+ "reference": "8dcfd392135a5bd938c3c83ea71419501ad9855d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/cf219ede922fb47956726f35e2127277ebd302ca",
- "reference": "cf219ede922fb47956726f35e2127277ebd302ca",
+ "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/8dcfd392135a5bd938c3c83ea71419501ad9855d",
+ "reference": "8dcfd392135a5bd938c3c83ea71419501ad9855d",
"shasum": ""
},
"require": {
@@ -5628,7 +5631,7 @@
],
"description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.",
"homepage": "https://github.com/theseer/fDOMDocument",
- "time": "2017-04-17T09:08:13+00:00"
+ "time": "2017-04-21T14:50:31+00:00"
},
{
"name": "webmozart/assert",
diff --git a/database/migrations/2017_04_25_203734_update_notes_table_add_swarm_url.php b/database/migrations/2017_04_25_203734_update_notes_table_add_swarm_url.php
new file mode 100644
index 00000000..4a161735
--- /dev/null
+++ b/database/migrations/2017_04_25_203734_update_notes_table_add_swarm_url.php
@@ -0,0 +1,32 @@
+string('swarm_url')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('notes', function (Blueprint $table) {
+ $table->dropColumn('swarm_url');
+ });
+ }
+}
diff --git a/database/migrations/2017_05_12_135451_update_places_table_add_foursquare_column.php b/database/migrations/2017_05_12_135451_update_places_table_add_foursquare_column.php
new file mode 100644
index 00000000..0e352aff
--- /dev/null
+++ b/database/migrations/2017_05_12_135451_update_places_table_add_foursquare_column.php
@@ -0,0 +1,32 @@
+string('foursquare')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('places', function (Blueprint $table) {
+ $table->dropColumn('foursquare');
+ });
+ }
+}
diff --git a/helpers.php b/helpers.php
new file mode 100644
index 00000000..d70efc56
--- /dev/null
+++ b/helpers.php
@@ -0,0 +1,199 @@
+ 80, 'https' => 443];
+ if (isset($url['scheme'])) {
+ $url['scheme'] = strtolower($url['scheme']);
+ // Strip scheme default ports
+ if (isset($defaultSchemes[$url['scheme']]) &&
+ isset($url['port']) &&
+ $defaultSchemes[$url['scheme']] == $url['port']
+ ) {
+ unset($url['port']);
+ }
+ $newUrl .= "{$url['scheme']}://";
+ }
+ if (isset($url['host'])) {
+ $url['host'] = mb_strtolower($url['host']);
+ $newUrl .= $url['host'];
+ }
+ if (isset($url['port'])) {
+ $newUrl .= ":{$url['port']}";
+ }
+
+ if (isset($url['path'])) {
+ // Case normalization
+ $url['path'] = normalizer_normalize($url['path'], Normalizer::FORM_C);
+ // Strip duplicate slashes
+ while (preg_match("/\/\//", $url['path'])) {
+ $url['path'] = preg_replace('/\/\//', '/', $url['path']);
+ }
+
+ /*
+ * Decode unreserved characters, http://www.apps.ietf.org/rfc/rfc3986.html#sec-2.3
+ * Heavily rewritten version of urlDecodeUnreservedChars() in Glen Scott's url-normalizer.
+ */
+ $u = [];
+ for ($o = 65; $o <= 90; $o++) {
+ $u[] = dechex($o);
+ }
+ for ($o = 97; $o <= 122; $o++) {
+ $u[] = dechex($o);
+ }
+ for ($o = 48; $o <= 57; $o++) {
+ $u[] = dechex($o);
+ }
+ $chrs = ['-', '.', '_', '~'];
+ foreach ($chrs as $chr) {
+ $u[] = dechex(ord($chr));
+ }
+ $url['path'] = preg_replace_callback(
+ array_map(
+ create_function('$str', 'return "/%" . strtoupper($str) . "/x";'),
+ $u
+ ),
+ create_function('$matches', 'return chr(hexdec($matches[0]));'),
+ $url['path']
+ );
+ // Remove directory index
+ $defaultIndexes = ["/default\.aspx/" => 'default.aspx/', "/default\.asp/" => 'default.asp/',
+ "/index\.html/" => 'index.html/', "/index\.htm/" => 'index.htm/',
+ "/default\.html/" => 'default.html/', "/default\.htm/" => 'default.htm/',
+ "/index\.php/" => 'index.php/', "/index\.jsp/" => 'index.jsp/', ];
+ foreach ($defaultIndexes as $index => $strip) {
+ if (preg_match($index, $url['path'])) {
+ $url['path'] = str_replace($strip, '', $url['path']);
+ }
+ }
+ // here we only want to drop a slash for the root domain
+ // e.g. http://example.com/ -> http://example.com
+ // but http://example.com/path/ -/-> http://example.com/path
+ if ($url['path'] == '/') {
+ unset($url['path']);
+ }
+
+ /**
+ * Path segment normalization, http://www.apps.ietf.org/rfc/rfc3986.html#sec-5.2.4
+ * Heavily rewritten version of removeDotSegments() in Glen Scott's url-normalizer.
+ */
+ $new_path = '';
+ while (! empty($url['path'])) {
+ if (preg_match('!^(\.\./|\./)!x', $url['path'])) {
+ $url['path'] = preg_replace('!^(\.\./|\./)!x', '', $url['path']);
+ } elseif (preg_match('!^(/\./)!x', $url['path'], $matches)
+ || preg_match('!^(/\.)$!x', $url['path'], $matches)) {
+ $url['path'] = preg_replace('!^' . $matches[1] . '!', '/', $url['path']);
+ } elseif (preg_match('!^(/\.\./|/\.\.)!x', $url['path'], $matches)) {
+ $url['path'] = preg_replace('!^' . preg_quote($matches[1], '!') . '!x', '/', $url['path']);
+ $new_path = preg_replace('!/([^/]+)$!x', '', $new_path);
+ } elseif (preg_match('!^(\.|\.\.)$!x', $url['path'])) {
+ $url['path'] = preg_replace('!^(\.|\.\.)$!x', '', $url['path']);
+ } else {
+ if (preg_match('!(/*[^/]*)!x', $url['path'], $matches)) {
+ $first_path_segment = $matches[1];
+ $url['path'] = preg_replace('/^' . preg_quote($first_path_segment, '/') . '/', '', $url['path'], 1);
+ $new_path .= $first_path_segment;
+ }
+ }
+ }
+ $newUrl .= $new_path;
+ }
+
+ if (isset($url['fragment'])) {
+ unset($url['fragment']);
+ }
+
+ // Sort GET params alphabetically, not because the RFC requires it but because it's cool!
+ if (isset($url['query'])) {
+ if (preg_match('/&/', $url['query'])) {
+ $s = explode('&', $url['query']);
+ $url['query'] = '';
+ sort($s);
+ foreach ($s as $z) {
+ $url['query'] .= "{$z}&";
+ }
+ $url['query'] = preg_replace('/&\Z/', '', $url['query']);
+ }
+ $newUrl .= "?{$url['query']}";
+ }
+
+ return $newUrl;
+ }
+}
+
+// sourced from https://stackoverflow.com/a/9776726
+if (! function_exists('prettyPrintJson')) {
+ function prettyPrintJson(string $json): string
+ {
+ $result = '';
+ $level = 0;
+ $in_quotes = false;
+ $in_escape = false;
+ $ends_line_level = null;
+ $json_length = strlen($json);
+
+ for ($i = 0; $i < $json_length; $i++) {
+ $char = $json[$i];
+ $new_line_level = null;
+ $post = '';
+ if ($ends_line_level !== null) {
+ $new_line_level = $ends_line_level;
+ $ends_line_level = null;
+ }
+ if ($in_escape) {
+ $in_escape = false;
+ } elseif ($char === '"') {
+ $in_quotes = ! $in_quotes;
+ } elseif (! $in_quotes) {
+ switch ($char) {
+ case '}':
+ case ']':
+ $level--;
+ $ends_line_level = null;
+ $new_line_level = $level;
+ break;
+ case '{':
+ case '[':
+ $level++;
+ //no break
+ case ',':
+ $ends_line_level = $level;
+ break;
+ case ':':
+ $post = ' ';
+ break;
+ case ' ':
+ case "\t":
+ case "\n":
+ case "\r":
+ $char = '';
+ $ends_line_level = $new_line_level;
+ $new_line_level = null;
+ break;
+ }
+ } elseif ($char === '\\') {
+ $in_escape = true;
+ }
+ if ($new_line_level !== null) {
+ $result .= "\n".str_repeat("\t", $new_line_level);
+ }
+ $result .= $char.$post;
+ }
+
+ return str_replace("\t", ' ', $result);
+ }
+}
diff --git a/package.json b/package.json
index e071c0af..9af1ac7b 100644
--- a/package.json
+++ b/package.json
@@ -6,15 +6,15 @@
"license": "CC0-1.0",
"dependencies": {
"alertify.js": "^1.0.12",
- "mapbox-gl": "^0.34.0",
+ "mapbox-gl": "0.37.0",
"marked": "^0.3.6",
- "normalize.css": "^5.0.0",
+ "normalize.css": "7.0.0",
"webStorage": "^1.2.2"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-core": "^6.21.0",
- "babel-loader": "^6.2.10",
+ "babel-loader": "7.0.0",
"babel-preset-env": "^1.2.2",
"babel-preset-es2015": "^6.18.0",
"babel-preset-latest": "^6.16.0",
diff --git a/routes/web.php b/routes/web.php
index ceaf1fb4..fe462895 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -89,21 +89,19 @@ Route::group(['domain' => config('url.longurl')], function () {
Route::get('blog/{year?}/{month?}', 'ArticlesController@index');
Route::get('blog/{year}/{month}/{slug}', 'ArticlesController@show');
- //micropub new notes page
- //this needs to be first so `notes/new` doesn't match `notes/{id}`
-
-
//Notes pages using NotesController
Route::get('notes', 'NotesController@index');
Route::get('notes/{id}', 'NotesController@show');
Route::get('note/{id}', 'NotesController@redirect');
Route::get('notes/tagged/{tag}', 'NotesController@tagged');
- //indieauth
+ // IndieAuth
Route::post('indieauth/start', 'IndieAuthController@start')->name('indieauth-start');
Route::get('indieauth/callback', 'IndieAuthController@callback')->name('indieauth-callback');
Route::get('logout', 'IndieAuthController@logout')->name('indieauth-logout');
- Route::post('api/token', 'IndieAuthController@tokenEndpoint'); //hmmm?
+
+ // Token Endpoint
+ Route::post('api/token', 'TokenEndpointController@create');
// Micropub Client
Route::get('micropub/create', 'MicropubClientController@create')->name('micropub-client');
@@ -118,7 +116,7 @@ Route::group(['domain' => config('url.longurl')], function () {
Route::post('micropub/media', 'MicropubClientController@processMedia')->name('process-media');
Route::get('micropub/media/clearlinks', 'MicropubClientController@clearLinks');
- // Micropub Endpoint
+ // Micropub Endpoints
Route::get('api/post', 'MicropubController@get')->middleware('micropub.token');
Route::post('api/post', 'MicropubController@post')->middleware('micropub.token');
Route::post('api/media', 'MicropubController@media')->middleware('micropub.token')->name('media-endpoint');
diff --git a/tests/Feature/MicropubControllerTest.php b/tests/Feature/MicropubControllerTest.php
index d91a627b..f1fd39a7 100644
--- a/tests/Feature/MicropubControllerTest.php
+++ b/tests/Feature/MicropubControllerTest.php
@@ -231,9 +231,9 @@ class MicropubControllerTest extends TestCase
$response
->assertJson([
'response' => 'error',
- 'error' => 'invalid_token'
+ 'error' => 'insufficient_scope'
])
- ->assertStatus(400);
+ ->assertStatus(401);
}
public function test_micropub_request_with_json_syntax_creates_new_place()
@@ -276,6 +276,47 @@ class MicropubControllerTest extends TestCase
->assertStatus(201);
}
+ public function test_micropub_request_with_json_syntax_update_replace_post()
+ {
+ $response = $this->json(
+ 'POST',
+ '/api/post',
+ [
+ 'action' => 'update',
+ 'url' => config('app.url') . '/notes/A',
+ 'replace' => [
+ 'content' => ['replaced content'],
+ ],
+ ],
+ ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
+ );
+ $response
+ ->assertJson(['response' => 'updated'])
+ ->assertStatus(200);
+ }
+
+ public function test_micropub_request_with_json_syntax_update_add_post()
+ {
+ $response = $this->json(
+ 'POST',
+ '/api/post',
+ [
+ 'action' => 'update',
+ 'url' => config('app.url') . '/notes/A',
+ 'add' => [
+ 'syndication' => ['https://www.swarmapp.com/checkin/123'],
+ ],
+ ],
+ ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
+ );
+ $response
+ ->assertJson(['response' => 'updated'])
+ ->assertStatus(200);
+ $this->assertDatabaseHas('notes', [
+ 'swarm_url' => 'https://www.swarmapp.com/checkin/123'
+ ]);
+ }
+
/**
* Generate a valid token to be used in the tests.
*
diff --git a/tests/Feature/SwarmTest.php b/tests/Feature/SwarmTest.php
new file mode 100644
index 00000000..8ae48974
--- /dev/null
+++ b/tests/Feature/SwarmTest.php
@@ -0,0 +1,69 @@
+json(
+ 'POST',
+ 'api/post',
+ [
+ 'type' => ['h-entry'],
+ 'properties' => [
+ 'published' => [\Carbon\Carbon::now()->toDateTimeString()],
+ 'syndication' => ['https://www.swarmapp.com/checkin/abc'],
+ 'content' => [[
+ 'value' => 'My first #checkin using Example Product',
+ 'html' => 'My first #checkin using Example Product',
+ ]],
+ 'checkin' => [[
+ 'type' => ['h-card'],
+ 'properties' => [
+ 'name' => ['Awesome Venue'],
+ 'url' => ['https://foursquare.com/v/123456'],
+ 'latitude' => ['1.23'],
+ 'longitude' => ['4.56'],
+ ],
+ ]],
+ ],
+ ],
+ ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]
+ );
+ $response
+ ->assertStatus(201)
+ ->assertJson(['response' => 'created']);
+ $this->assertDatabaseHas('places', [
+ 'foursquare' => 'https://foursquare.com/v/123456'
+ ]);
+ }
+
+ /**
+ * Generate a valid token to be used in the tests.
+ *
+ * @return Lcobucci\JWT\Token\Plain $token
+ */
+ private function getToken()
+ {
+ $signer = new Sha256();
+ $token = (new Builder())
+ ->set('client_id', 'https://ownyourswarm.p3k.io')
+ ->set('me', 'https://jonnybarnes.localhost')
+ ->set('scope', 'create update')
+ ->set('issued_at', time())
+ ->sign($signer, env('APP_KEY'))
+ ->getToken();
+
+ return $token;
+ }
+}
diff --git a/tests/Feature/TokenEndpointTest.php b/tests/Feature/TokenEndpointTest.php
new file mode 100644
index 00000000..964c9211
--- /dev/null
+++ b/tests/Feature/TokenEndpointTest.php
@@ -0,0 +1,38 @@
+shouldReceive('discoverAuthorizationEndpoint')
+ ->with(normalize_url(config('app.url')))
+ ->once()
+ ->andReturn('https://indieauth.com/auth');
+ $mockClient->shouldReceive('verifyIndieAuthCode')
+ ->andReturn([
+ 'me' => config('app.url'),
+ 'scope' => 'create update',
+ ]);
+ $this->app->instance(Client::class, $mockClient);
+ $response = $this->post('/api/token', [
+ 'me' => config('app.url'),
+ 'code' => 'abc123',
+ 'redirect_uri' => route('indieauth-callback'),
+ 'client_id' => route('micropub-client'),
+ 'state' => mt_rand(1000, 10000),
+ ]);
+ parse_str($response->content(), $output);
+ $this->assertEquals(config('app.url'), $output['me']);
+ $this->assertTrue(array_key_exists('access_token', $output));
+ }
+}
diff --git a/tests/Unit/HelpersTest.php b/tests/Unit/HelpersTest.php
new file mode 100644
index 00000000..9b31e4f3
--- /dev/null
+++ b/tests/Unit/HelpersTest.php
@@ -0,0 +1,69 @@
+assertEquals(normalize_url(normalize_url($input)), normalize_url($input));
+ }
+
+ /**
+ * @dataProvider urlProvider
+ */
+ public function test_normalize_url($input, $output)
+ {
+ $this->assertEquals($output, normalize_url($input));
+ }
+
+ public function urlProvider()
+ {
+ return [
+ ['https://example.org/', 'https://example.org'],
+ ['https://example.org:443/', 'https://example.org'],
+ ['http://www.foo.bar/index.php/', 'http://www.foo.bar'],
+ ['https://example.org/?foo=bar&baz=true', 'https://example.org?baz=true&foo=bar'],
+ ];
+ }
+
+ public function test_pretty_print_json()
+ {
+ $json = <<assertEquals($expected, prettyPrintJson($json));
+ }
+}
diff --git a/tinker.config.php b/tinker.config.php
new file mode 100644
index 00000000..63111c79
--- /dev/null
+++ b/tinker.config.php
@@ -0,0 +1,38 @@
+files()->name('*.php')->in(base_path().'/app');
+ foreach ($finder as $file) {
+ $namespace = 'App\\';
+ if ($relativePath = $file->getRelativePath()) {
+ $namespace .= strtr($relativePath, '/', '\\') . '\\';
+ }
+ $class = $namespace . $file->getBasename('.php');
+ try {
+ $r = new \ReflectionClass($class);
+ if ($r->isSubclassOf('Illuminate\\Database\\Eloquent\\Model')) {
+ class_alias($class, $file->getBasename('.php'));
+ }
+ } catch (Exception $e) {
+ //
+ }
+ }
+ }
+}
+
+aliasModels();
+
+return [
+ 'startupMessage' => 'Using local config file (tinker.config.php)',
+
+ 'commands' => [
+ // new \App\Tinker\TestCommand,
+ ],
+];
diff --git a/yarn.lock b/yarn.lock
index c4aa7ce1..a7415b99 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -48,17 +48,21 @@ acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
-acorn@^4.0.0, acorn@^4.0.3, acorn@^4.0.4:
+acorn@^4.0.0, acorn@^4.0.3:
version "4.0.11"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0"
+acorn@^5.0.0:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
+
ajv-keywords@^1.1.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
ajv@^4.7.0, ajv@^4.9.1:
- version "4.11.6"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.6.tgz#947e93049790942b2a2d60a8289b28924d39f987"
+ version "4.11.8"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
dependencies:
co "^4.6.0"
json-stable-stringify "^1.0.1"
@@ -117,11 +121,11 @@ archy@^1.0.0:
resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
are-we-there-yet@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3"
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d"
dependencies:
delegates "^1.0.0"
- readable-stream "^2.0.0 || ^1.1.13"
+ readable-stream "^2.0.6"
argparse@^1.0.7:
version "1.0.9"
@@ -136,8 +140,8 @@ arr-diff@^2.0.0:
arr-flatten "^1.0.1"
arr-flatten@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b"
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1"
array-unique@^0.2.1:
version "0.2.1"
@@ -182,8 +186,8 @@ async-each@^1.0.0:
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
async@^2.1.2:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/async/-/async-2.3.0.tgz#1013d1051047dd320fe24e494d5c66ecaf6147d9"
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.4.0.tgz#4990200f18ea5b837c2cc4f8c031a6985c385611"
dependencies:
lodash "^4.14.0"
@@ -374,14 +378,13 @@ babel-helpers@^6.24.1:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
-babel-loader@^6.2.10:
- version "6.4.1"
- resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca"
+babel-loader@7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.0.0.tgz#2e43a66bee1fff4470533d0402c8a4532fafbaf7"
dependencies:
find-cache-dir "^0.1.1"
- loader-utils "^0.2.16"
+ loader-utils "^1.0.2"
mkdirp "^0.5.1"
- object-assign "^4.0.1"
babel-messages@^6.23.0:
version "6.23.0"
@@ -613,8 +616,8 @@ babel-polyfill@^6.23.0:
regenerator-runtime "^0.10.0"
babel-preset-env@^1.2.2:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.3.3.tgz#5913407784e3d98de2aa814a3ef9059722b34e0b"
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.4.0.tgz#c8e02a3bcc7792f23cded68e0355b9d4c28f0f7a"
dependencies:
babel-plugin-check-es2015-constants "^6.22.0"
babel-plugin-syntax-trailing-function-commas "^6.22.0"
@@ -749,8 +752,8 @@ babel-types@^6.19.0, babel-types@^6.24.1:
to-fast-properties "^1.0.1"
babylon@^6.11.0, babylon@^6.15.0:
- version "6.16.1"
- resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3"
+ version "6.17.1"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.1.tgz#17f14fddf361b695981fe679385e4f1c01ebd86f"
balanced-match@^0.4.1:
version "0.4.2"
@@ -778,6 +781,10 @@ binary-extensions@^1.0.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774"
+bindings@1.2.x:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.2.1.tgz#14ad6113812d2d37d72e67b4cacb4bb726505f11"
+
block-stream@*:
version "0.0.9"
resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
@@ -812,7 +819,7 @@ boxen@^0.3.1:
string-width "^1.0.1"
widest-line "^1.0.0"
-brace-expansion@^1.0.0:
+brace-expansion@^1.0.0, brace-expansion@^1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59"
dependencies:
@@ -967,8 +974,8 @@ camelcase@^3.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
caniuse-db@^1.0.30000639:
- version "1.0.30000650"
- resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000650.tgz#615f564d367533d32b82d72ada09661e75386bab"
+ version "1.0.30000666"
+ resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000666.tgz#951ed9f3d3bfaa08a06dafbb5089ab07cce6ab90"
capture-stack-trace@^1.0.0:
version "1.0.0"
@@ -996,8 +1003,8 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
supports-color "^2.0.0"
chokidar@^1.4.3, chokidar@^1.6.1:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
anymatch "^1.3.0"
async-each "^1.0.0"
@@ -1010,7 +1017,7 @@ chokidar@^1.4.3, chokidar@^1.6.1:
optionalDependencies:
fsevents "^1.0.0"
-cipher-base@^1.0.0, cipher-base@^1.0.1:
+cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.3.tgz#eeabf194419ce900da3018c207d212f2a6df0a07"
dependencies:
@@ -1095,7 +1102,7 @@ concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-concat-stream@^1.4.7:
+concat-stream@^1.4.7, concat-stream@~1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
dependencies:
@@ -1109,14 +1116,6 @@ concat-stream@~1.2.1:
dependencies:
bops "0.0.6"
-concat-stream@~1.4.5:
- version "1.4.10"
- resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.4.10.tgz#acc3bbf5602cb8cc980c6ac840fa7d8603e3ef36"
- dependencies:
- inherits "~2.0.1"
- readable-stream "~1.1.9"
- typedarray "~0.0.5"
-
configstore@^1.0.0, configstore@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/configstore/-/configstore-1.4.0.tgz#c35781d0501d268c25c54b8b17f6240e8a4fb021"
@@ -1196,21 +1195,25 @@ create-error-class@^3.0.1:
dependencies:
capture-stack-trace "^1.0.0"
-create-hash@^1.1.0, create-hash@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.2.tgz#51210062d7bb7479f6c65bb41a92208b1d61abad"
+create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd"
dependencies:
cipher-base "^1.0.1"
inherits "^2.0.1"
- ripemd160 "^1.0.0"
- sha.js "^2.3.6"
+ ripemd160 "^2.0.0"
+ sha.js "^2.4.0"
-create-hmac@^1.1.0, create-hmac@^1.1.2:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.4.tgz#d3fb4ba253eb8b3f56e39ea2fbcb8af747bd3170"
+create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06"
dependencies:
+ cipher-base "^1.0.3"
create-hash "^1.1.0"
inherits "^2.0.1"
+ ripemd160 "^2.0.0"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
cross-spawn@^5.0.1:
version "5.1.0"
@@ -1248,18 +1251,18 @@ dashdash@^1.12.0:
assert-plus "^1.0.0"
date-fns@^1.27.2:
- version "1.28.2"
- resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.28.2.tgz#19e4192d68875c0bf7c9537e3f296a8ec64853ef"
+ version "1.28.4"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.28.4.tgz#7938aec34ba31fc8bd134d2344bc2e0bbfd95165"
date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
debug@^2.1.1, debug@^2.2.0:
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d"
+ version "2.6.6"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a"
dependencies:
- ms "0.7.2"
+ ms "0.7.3"
decamelize@^1.0.0, decamelize@^1.1.1:
version "1.2.0"
@@ -1270,8 +1273,8 @@ deep-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
deep-extend@~0.4.0:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
deep-is@~0.1.3:
version "0.1.3"
@@ -1348,8 +1351,8 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0"
electron-to-chromium@^1.2.7:
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.3.tgz#651eb63fe89f39db70ffc8dbd5d9b66958bc6a0e"
+ version "1.3.10"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.10.tgz#63d62b785471f0d8dda85199d64579de8a449f08"
elegant-spinner@^1.0.1:
version "1.0.1"
@@ -1521,8 +1524,8 @@ expand-range@^1.8.1:
fill-range "^2.1.0"
extend@~3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4"
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
extglob@^0.3.1:
version "0.3.2"
@@ -1555,8 +1558,8 @@ figures@^1.3.5, figures@^1.7.0:
object-assign "^4.1.0"
filename-regex@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775"
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
fill-range@^2.1.0:
version "2.2.3"
@@ -1588,8 +1591,8 @@ find-up@^1.0.0:
pinkie-promise "^2.0.0"
flow-remove-types@^1.1.2:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-1.2.0.tgz#c285516eabba72177a1b10bfb58f6ffb675a8877"
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/flow-remove-types/-/flow-remove-types-1.2.1.tgz#58e261bf8b842bd234c86cafb982a1213aff0edb"
dependencies:
babylon "^6.15.0"
vlq "^0.2.1"
@@ -1656,9 +1659,9 @@ function-bind@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
-gauge@~2.7.1:
- version "2.7.3"
- resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09"
+gauge@~2.7.3:
+ version "2.7.4"
+ resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
dependencies:
aproba "^1.0.3"
console-control-strings "^1.0.0"
@@ -1696,8 +1699,8 @@ get-stream@^3.0.0:
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
getpass@^0.1.1:
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6"
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
@@ -1817,6 +1820,12 @@ hasbin@^1.2.3:
dependencies:
async "~1.5"
+hash-base@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1"
+ dependencies:
+ inherits "^2.0.1"
+
hash.js@^1.0.0, hash.js@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.0.3.tgz#1332ff00156c0a0ffdd8236013d07b77a0451573"
@@ -1852,8 +1861,8 @@ home-or-tmp@^2.0.0:
os-tmpdir "^1.0.1"
hosted-git-info@^2.1.4:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.1.tgz#4b0445e41c004a8bd1337773a4ff790ca40318c8"
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67"
http-signature@~1.1.0:
version "1.1.1"
@@ -1931,8 +1940,8 @@ inquirer@1.0.3:
through "^2.3.6"
interpret@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.2.tgz#f4f623f0bb7122f15f5717c8e254b8161b5c5b2d"
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
invariant@^2.2.0, invariant@^2.2.2:
version "2.2.2"
@@ -1954,7 +1963,7 @@ is-binary-path@^1.0.0:
dependencies:
binary-extensions "^1.0.0"
-is-buffer@^1.0.2:
+is-buffer@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
@@ -1994,6 +2003,10 @@ is-fullwidth-code-point@^1.0.0:
dependencies:
number-is-nan "^1.0.0"
+is-fullwidth-code-point@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+
is-glob@^2.0.0, is-glob@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
@@ -2079,8 +2092,8 @@ js-tokens@^3.0.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
js-yaml@^3.4.3, js-yaml@^3.5.3:
- version "3.8.3"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.3.tgz#33a05ec481c850c8875929166fe1beb61c728766"
+ version "3.8.4"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6"
dependencies:
argparse "^1.0.7"
esprima "^3.1.1"
@@ -2115,7 +2128,7 @@ json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
-json5@^0.5.0:
+json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
@@ -2137,10 +2150,10 @@ kdbush@^1.0.1:
resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-1.0.1.tgz#3cbd03e9dead9c0f6f66ccdb96450e5cecc640e0"
kind-of@^3.0.2:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47"
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.0.tgz#b58abe4d5c044ad33726a8c1525b48cf891bff07"
dependencies:
- is-buffer "^1.0.2"
+ is-buffer "^1.1.5"
latest-version@^1.0.0:
version "1.0.1"
@@ -2172,13 +2185,13 @@ levn@~0.3.0:
type-check "~0.3.2"
lint-staged@^3.2.1:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-3.4.0.tgz#52fa85dfc92bb1c6fe8ad0d0d98ca13924e03e4b"
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-3.4.1.tgz#96cd1cf7a1ac92d81662643c37d1cca28b91b046"
dependencies:
app-root-path "^2.0.0"
cosmiconfig "^1.1.0"
execa "^0.6.0"
- listr "^0.11.0"
+ listr "^0.12.0"
minimatch "^3.0.0"
npm-which "^3.0.1"
staged-git-files "0.0.4"
@@ -2209,9 +2222,9 @@ listr-verbose-renderer@^0.4.0:
date-fns "^1.27.2"
figures "^1.7.0"
-listr@^0.11.0:
- version "0.11.0"
- resolved "https://registry.yarnpkg.com/listr/-/listr-0.11.0.tgz#5e778bc23806ac3ab984ed75564458151f39b03e"
+listr@^0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a"
dependencies:
chalk "^1.1.3"
cli-truncate "^0.2.1"
@@ -2225,6 +2238,7 @@ listr@^0.11.0:
log-symbols "^1.0.2"
log-update "^1.0.2"
ora "^0.2.3"
+ p-map "^1.1.1"
rxjs "^5.0.0-beta.11"
stream-to-observable "^0.1.0"
strip-ansi "^3.0.1"
@@ -2252,6 +2266,14 @@ loader-utils@^0.2.16:
json5 "^0.5.0"
object-assign "^4.0.1"
+loader-utils@^1.0.2:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
+ dependencies:
+ big.js "^3.1.3"
+ emojis-list "^2.0.0"
+ json5 "^0.5.0"
+
lodash.assign@^4.0.3, lodash.assign@^4.0.6:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
@@ -2320,9 +2342,9 @@ mapbox-gl-supported@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mapbox-gl-supported/-/mapbox-gl-supported-1.2.0.tgz#cbd34df894206cadda9a33c8d9a4609f26bb1989"
-mapbox-gl@^0.34.0:
- version "0.34.0"
- resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-0.34.0.tgz#f35effae360b8174b7466476a400cc1306a19713"
+mapbox-gl@0.37.0:
+ version "0.37.0"
+ resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-0.37.0.tgz#20103b0ae73a0e77fe9405439749318b87c04f10"
dependencies:
"@mapbox/gl-matrix" "^0.0.1"
"@mapbox/shelf-pack" "^3.0.0"
@@ -2377,6 +2399,13 @@ micromatch@^2.1.5:
parse-glob "^3.0.4"
regex-cache "^0.4.2"
+microtime@^2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/microtime/-/microtime-2.1.3.tgz#0d1307f25da0ca7fde4ab791edc8c91dd7b4e3be"
+ dependencies:
+ bindings "1.2.x"
+ nan "2.6.x"
+
miller-rabin@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d"
@@ -2409,10 +2438,10 @@ minimatch@3.0.2:
brace-expansion "^1.0.0"
minimatch@^3.0.0, minimatch@^3.0.2:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
- brace-expansion "^1.0.0"
+ brace-expansion "^1.1.7"
minimist@0.0.5:
version "0.0.5"
@@ -2432,9 +2461,9 @@ minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0:
dependencies:
minimist "0.0.8"
-ms@0.7.2:
- version "0.7.2"
- resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
+ms@0.7.3:
+ version "0.7.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff"
multi-stage-sourcemap@^0.2.1:
version "0.2.1"
@@ -2446,9 +2475,9 @@ mute-stream@0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db"
-nan@^2.3.0:
- version "2.6.1"
- resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.1.tgz#8c84f7b14c96b89f57fbc838012180ec8ca39a01"
+nan@2.6.x, nan@^2.3.0:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
nconf@^0.7.2:
version "0.7.2"
@@ -2518,8 +2547,8 @@ nopt@^4.0.1:
osenv "^0.1.4"
normalize-package-data@^2.3.2:
- version "2.3.6"
- resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.6.tgz#498fa420c96401f787402ba21e600def9f981fff"
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb"
dependencies:
hosted-git-info "^2.1.4"
is-builtin-module "^1.0.0"
@@ -2532,9 +2561,9 @@ normalize-path@^2.0.1:
dependencies:
remove-trailing-separator "^1.0.1"
-normalize.css@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-5.0.0.tgz#7cec875ce8178a5333c4de80b68ea9c18b9d7c37"
+normalize.css@7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-7.0.0.tgz#abfb1dd82470674e0322b53ceb1aaf412938e4bf"
npm-path@^2.0.2:
version "2.0.3"
@@ -2557,12 +2586,12 @@ npm-which@^3.0.1:
which "^1.2.10"
npmlog@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f"
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.0.tgz#dc59bee85f64f00ed424efb2af0783df25d1c0b5"
dependencies:
are-we-there-yet "~1.1.2"
console-control-strings "~1.1.0"
- gauge "~2.7.1"
+ gauge "~2.7.3"
set-blocking "~2.0.0"
number-is-nan@^1.0.0:
@@ -2694,6 +2723,10 @@ p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+p-map@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a"
+
package-json-versionify@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/package-json-versionify/-/package-json-versionify-1.0.4.tgz#5860587a944873a6b7e6d26e8e51ffb22315bf17"
@@ -2783,10 +2816,16 @@ pbf@^1.3.2:
resolve-protobuf-schema "^2.0.0"
pbkdf2@^3.0.3:
- version "3.0.9"
- resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.9.tgz#f2c4b25a600058b3c3773c086c37dbbee1ffe693"
+ version "3.0.11"
+ resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.11.tgz#791b7414e50c848438976e12ea2651003037ca6b"
dependencies:
- create-hmac "^1.1.2"
+ create-hash "^1.1.2"
+ create-hmac "^1.1.4"
+ ripemd160 "^2.0.1"
+ safe-buffer "^5.0.1"
+ sha.js "^2.4.8"
+ optionalDependencies:
+ microtime "^2.1.3"
performance-now@^0.2.0:
version "0.2.0"
@@ -2845,8 +2884,8 @@ process-nextick-args@~1.0.6:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
process@^0.11.0:
- version "0.11.9"
- resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1"
+ version "0.11.10"
+ resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
"promise@>=3.2 <8":
version "7.1.1"
@@ -2876,11 +2915,11 @@ public-encrypt@^4.0.0:
parse-asn1 "^5.0.0"
randombytes "^2.0.1"
-punycode@1.3.2:
+punycode@1.3.2, punycode@^1.2.4:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
-punycode@^1.2.4, punycode@^1.4.1:
+punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
@@ -2957,7 +2996,7 @@ read-pkg@^1.0.0:
normalize-package-data "^2.3.2"
path-type "^1.0.0"
-readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6:
+readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6:
version "2.2.9"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8"
dependencies:
@@ -3001,8 +3040,8 @@ regenerate@^1.2.1:
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
regenerator-runtime@^0.10.0:
- version "0.10.3"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e"
+ version "0.10.5"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
regenerator-transform@0.9.11:
version "0.9.11"
@@ -3028,10 +3067,11 @@ regexpu-core@^2.0.0:
regjsparser "^0.1.4"
registry-auth-token@^3.0.1:
- version "3.1.2"
- resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.1.2.tgz#1b9e51a185c930da34a9894b12a52ea998f1adaf"
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006"
dependencies:
rc "^1.1.6"
+ safe-buffer "^5.0.1"
registry-url@^3.0.0, registry-url@^3.0.3:
version "3.1.0"
@@ -3119,8 +3159,8 @@ resolve-protobuf-schema@^2.0.0:
protocol-buffers-schema "^2.0.2"
resolve@^1.1.5:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235"
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
dependencies:
path-parse "^1.0.5"
@@ -3143,9 +3183,12 @@ rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1:
dependencies:
glob "^7.0.5"
-ripemd160@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-1.0.1.tgz#93a4bbd4942bc574b69a8fa57c71de10ecca7d6e"
+ripemd160@^2.0.0, ripemd160@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7"
+ dependencies:
+ hash-base "^2.0.0"
+ inherits "^2.0.1"
run-async@^2.2.0:
version "2.3.0"
@@ -3158,8 +3201,8 @@ rx@^4.1.0:
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
rxjs@^5.0.0-beta.11:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.3.0.tgz#d88ccbdd46af290cbdb97d5d8055e52453fabe2d"
+ version "5.4.0"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.0.tgz#a7db14ab157f9d7aac6a56e655e7a3860d39bf26"
dependencies:
symbol-observable "^1.0.1"
@@ -3189,7 +3232,7 @@ setimmediate@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
-sha.js@^2.3.6:
+sha.js@^2.4.0, sha.js@^2.4.8:
version "2.4.8"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f"
dependencies:
@@ -3309,8 +3352,8 @@ snyk-try-require@^1.1.1, snyk-try-require@^1.2.0:
then-fs "^2.0.0"
snyk@^1.14.3:
- version "1.28.0"
- resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.28.0.tgz#f805cc5917d57203aa7fe055650e70d1b31daba2"
+ version "1.30.0"
+ resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.30.0.tgz#a323809ea477d6aff0e325f5995cb491c0d7ca3d"
dependencies:
abbrev "^1.0.7"
ansi-escapes "^1.3.0"
@@ -3340,12 +3383,12 @@ snyk@^1.14.3:
uuid "^3.0.1"
source-list-map@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.1.tgz#1a33ac210ca144d1e561f906ebccab5669ff4cb4"
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1"
source-map-support@^0.4.2:
- version "0.4.14"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.14.tgz#9d4463772598b86271b4f523f6c1f4e02a7d6aef"
+ version "0.4.15"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
dependencies:
source-map "^0.5.6"
@@ -3391,8 +3434,8 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
sshpk@^1.7.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.11.0.tgz#2d8d5ebb4a6fab28ffba37fa62a90f4a3ea59d77"
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
@@ -3416,10 +3459,10 @@ static-eval@~0.2.0:
escodegen "~0.0.24"
static-module@^1.1.0:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/static-module/-/static-module-1.3.1.tgz#79071d340e4419e4ab5ce87976a9eb67250c8493"
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/static-module/-/static-module-1.3.2.tgz#329fb9f223a566266bda71843b7d932c767174f3"
dependencies:
- concat-stream "~1.4.5"
+ concat-stream "~1.6.0"
duplexer2 "~0.0.2"
escodegen "~1.3.2"
falafel "^1.0.0"
@@ -3439,8 +3482,8 @@ stream-browserify@^2.0.1:
readable-stream "^2.0.2"
stream-http@^2.3.1:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.0.tgz#cec1f4e3b494bc4a81b451808970f8b20b4ed5f6"
+ version "2.7.1"
+ resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.1.tgz#546a51741ad5a6b07e9e31b0b10441a917df528a"
dependencies:
builtin-status-codes "^3.0.0"
inherits "^2.0.1"
@@ -3470,6 +3513,13 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
+string-width@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e"
+ dependencies:
+ is-fullwidth-code-point "^2.0.0"
+ strip-ansi "^3.0.0"
+
string_decoder@^0.10.25, string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
@@ -3607,8 +3657,8 @@ to-arraybuffer@^1.0.0:
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
to-fast-properties@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
to-utf8@0.0.1:
version "0.0.1"
@@ -3644,13 +3694,13 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
-typedarray@^0.0.6, typedarray@~0.0.5:
+typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
uglify-js@^2.8.5:
- version "2.8.22"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.22.tgz#d54934778a8da14903fa29a326fb24c0ab51a1a0"
+ version "2.8.23"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.23.tgz#8230dd9783371232d62a7821e2cf9a817270a8a0"
dependencies:
source-map "~0.5.1"
yargs "~3.10.0"
@@ -3762,8 +3812,8 @@ uuid@^3.0.0, uuid@^3.0.1:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
v8flags@^2.0.10:
- version "2.0.12"
- resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.12.tgz#73235d9f7176f8e8833fb286795445f7938d84e5"
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4"
dependencies:
user-home "^1.1.1"
@@ -3787,8 +3837,8 @@ verror@1.3.6:
extsprintf "1.0.2"
vlq@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.1.tgz#14439d711891e682535467f8587c5630e4222a6c"
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.2.tgz#e316d5257b40b86bb43cb8d5fea5d7f54d6b0ca1"
vm-browserify@0.0.4:
version "0.0.4"
@@ -3826,10 +3876,10 @@ webpack-sources@^0.2.3:
source-map "~0.5.3"
webpack@^2.2.0:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.3.3.tgz#eecc083c18fb7bf958ea4f40b57a6640c5a0cc78"
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.5.1.tgz#61742f0cf8af555b87460a9cd8bba2f1e3ee2fce"
dependencies:
- acorn "^4.0.4"
+ acorn "^5.0.0"
acorn-dynamic-import "^2.0.0"
ajv "^4.7.0"
ajv-keywords "^1.1.1"
@@ -3837,6 +3887,7 @@ webpack@^2.2.0:
enhanced-resolve "^3.0.0"
interpret "^1.0.0"
json-loader "^0.5.4"
+ json5 "^0.5.1"
loader-runner "^2.3.0"
loader-utils "^0.2.16"
memory-fs "~0.4.1"
@@ -3869,10 +3920,10 @@ which@1.2.x, which@^1.2.10, which@^1.2.9:
isexe "^2.0.0"
wide-align@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad"
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.1.tgz#d2ea8aa2db2e66467e8b60cc3e897de3bc4429e6"
dependencies:
- string-width "^1.0.1"
+ string-width "^2.0.0"
widest-line@^1.0.0:
version "1.0.0"
@@ -3918,8 +3969,8 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
write-file-atomic@^1.1.2:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.1.tgz#7d45ba32316328dd1ec7d90f60ebc0d845bb759a"
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f"
dependencies:
graceful-fs "^4.1.11"
imurmurhash "^0.1.4"