Merge branch 'master' into framework-import-process+activity

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
pull/226/head
Maxence Lange 2018-12-19 00:13:33 -01:00
rodzic 47c658c32b
commit 37a889d978
33 zmienionych plików z 1280 dodań i 243 usunięć

Wyświetl plik

@ -4,6 +4,71 @@ clone:
depth: 1
pipeline:
check-app-compatbility:
image: nextcloudci/php7.0:php7.0-17
environment:
- APP_NAME=social
- CORE_BRANCH=stable15
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server
# Code checker
- ./occ app:check-code $APP_NAME -c strong-comparison
- ./occ app:check-code $APP_NAME -c deprecation
when:
matrix:
TESTS: check-app-compatbility
syntax-php7.0:
image: nextcloudci/php7.0:php7.0-17
environment:
- APP_NAME=social
- CORE_BRANCH=stable15
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php7.0
syntax-php7.1:
image: nextcloudci/php7.1:php7.1-15
environment:
- APP_NAME=social
- CORE_BRANCH=stable15
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php7.1
syntax-php7.2:
image: nextcloudci/php7.2:php7.2-9
environment:
- APP_NAME=social
- CORE_BRANCH=stable15
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php7.2
syntax-php7.3:
image: nextcloudci/php7.3:php7.3-2
environment:
- APP_NAME=social
- CORE_BRANCH=stable15
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php7.3
eslint:
image: nextcloudci/jsunit:jsunit-5
commands:
@ -12,7 +77,6 @@ pipeline:
when:
matrix:
TESTS: eslint
vue-build:
image: nextcloudci/jsunit:jsunit-5
commands:
@ -20,10 +84,15 @@ pipeline:
- npm run build
when:
matrix:
TESTS:vue-build
TESTS: vue-build
matrix:
include:
- TESTS: check-app-compatbility
- TESTS: syntax-php7.0
- TESTS: syntax-php7.1
- TESTS: syntax-php7.2
- TESTS: syntax-php7.3
- TESTS: eslint
- TESTS: vue-build

Wyświetl plik

@ -26,25 +26,24 @@
<namespace>Social</namespace>
<category>social</category>
<website>https://github.com/nextcloud/social</website>
<repository type="git">https://github.com/nextcloud/social.git</repository>
<bugs>https://github.com/nextcloud/social/issues</bugs>
<repository type="git">https://github.com/nextcloud/social.git</repository>
<screenshot>https://raw.githubusercontent.com/nextcloud/social/master/img/screenshot.png</screenshot>
<dependencies>
<nextcloud min-version="15" max-version="16"/>
</dependencies>
<navigations>
<navigation>
<name>Social</name>
<route>social.Navigation.navigate</route>
<order>6</order>
</navigation>
</navigations>
<background-jobs>
<job>OCA\Social\Cron\Cache</job>
<job>OCA\Social\Cron\Queue</job>
</background-jobs>
<repair-steps>
<post-migration>
<step>OCA\Social\Migration\CheckInstallation</step>
</post-migration>
</repair-steps>
<commands>
<command>OCA\Social\Command\CacheRefresh</command>
<command>OCA\Social\Command\NoteCreate</command>
@ -52,4 +51,11 @@
<command>OCA\Social\Command\QueueProcess</command>
</commands>
<navigations>
<navigation>
<name>Social</name>
<route>social.Navigation.navigate</route>
<order>6</order>
</navigation>
</navigations>
</info>

Wyświetl plik

@ -65,6 +65,7 @@ return [
['name' => 'SocialPub#displayPost', 'url' => '/@{username}/{postId}', 'verb' => 'GET'],
['name' => 'Local#streamHome', 'url' => '/api/v1/stream/home', 'verb' => 'GET'],
['name' => 'Local#streamNotifications', 'url' => '/api/v1/stream/notifications', 'verb' => 'GET'],
['name' => 'Local#streamTimeline', 'url' => '/api/v1/stream/timeline', 'verb' => 'GET'],
['name' => 'Local#streamFederated', 'url' => '/api/v1/stream/federated', 'verb' => 'GET'],
['name' => 'Local#streamDirect', 'url' => '/api/v1/stream/direct', 'verb' => 'GET'],

Wyświetl plik

@ -10,6 +10,10 @@
}
],
"require": {
"daita/my-small-php-tools": "dev-master"
"daita/my-small-php-tools": "dev-master",
"digitalbazaar/json-ld": "0.4.7"
},
"require-dev": {
"jakub-onderka/php-parallel-lint": "^1.0"
}
}

109
composer.lock wygenerowano
Wyświetl plik

@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "02220c2a6087d409a5e53060ee20c47e",
"content-hash": "2c21b8c338f3d2f929f349df19edbc0e",
"packages": [
{
"name": "daita/my-small-php-tools",
@ -12,12 +12,12 @@
"source": {
"type": "git",
"url": "https://github.com/daita/my-small-php-tools.git",
"reference": "7a61e966ac2a01db6fd0096f77620a7db978af18"
"reference": "29754f18951856a22c0fd5fc388b6162ea98fe8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/7a61e966ac2a01db6fd0096f77620a7db978af18",
"reference": "7a61e966ac2a01db6fd0096f77620a7db978af18",
"url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/29754f18951856a22c0fd5fc388b6162ea98fe8a",
"reference": "29754f18951856a22c0fd5fc388b6162ea98fe8a",
"shasum": ""
},
"require": {
@ -40,10 +40,105 @@
}
],
"description": "My small PHP Tools",
"time": "2018-12-04T10:09:31+00:00"
"time": "2018-12-18T00:38:01+00:00"
},
{
"name": "digitalbazaar/json-ld",
"version": "0.4.7",
"source": {
"type": "git",
"url": "https://github.com/digitalbazaar/php-json-ld.git",
"reference": "dc1bd23f0ee2efd27ccf636d32d2738dabcee182"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/digitalbazaar/php-json-ld/zipball/dc1bd23f0ee2efd27ccf636d32d2738dabcee182",
"reference": "dc1bd23f0ee2efd27ccf636d32d2738dabcee182",
"shasum": ""
},
"require": {
"ext-json": "*",
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"files": [
"jsonld.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Digital Bazaar, Inc.",
"email": "support@digitalbazaar.com"
}
],
"description": "A JSON-LD Processor and API implementation in PHP.",
"homepage": "https://github.com/digitalbazaar/php-json-ld",
"keywords": [
"JSON-LD",
"Linked Data",
"RDF",
"Semantic Web",
"json",
"jsonld"
],
"time": "2016-04-25T04:17:52+00:00"
}
],
"packages-dev": [
{
"name": "jakub-onderka/php-parallel-lint",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/JakubOnderka/PHP-Parallel-Lint.git",
"reference": "04fbd3f5fb1c83f08724aa58a23db90bd9086ee8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/JakubOnderka/PHP-Parallel-Lint/zipball/04fbd3f5fb1c83f08724aa58a23db90bd9086ee8",
"reference": "04fbd3f5fb1c83f08724aa58a23db90bd9086ee8",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"jakub-onderka/php-console-highlighter": "~0.3",
"nette/tester": "~1.3",
"squizlabs/php_codesniffer": "~2.7"
},
"suggest": {
"jakub-onderka/php-console-highlighter": "Highlight syntax in code snippet"
},
"bin": [
"parallel-lint"
],
"type": "library",
"autoload": {
"classmap": [
"./"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Jakub Onderka",
"email": "ahoj@jakubonderka.cz"
}
],
"description": "This tool check syntax of PHP files about 20x faster than serial check.",
"homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint",
"time": "2018-02-24T15:31:20+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {

Wyświetl plik

@ -126,8 +126,6 @@ class AccountController extends Controller {
*
* @PublicPage
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
* @param string $username
*

Wyświetl plik

@ -34,8 +34,21 @@ use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse;
use Exception;
use OC\AppFramework\Http;
use OCA\Social\AppInfo\Application;
use OCA\Social\Db\NotesRequest;
use OCA\Social\Exceptions\ActivityPubFormatException;
use OCA\Social\Exceptions\InvalidResourceEntryException;
use OCA\Social\Exceptions\InvalidResourceException;
use OCA\Social\Exceptions\Request410Exception;
use OCA\Social\Exceptions\RequestException;
use OCA\Social\Exceptions\SignatureIsGoneException;
use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Exceptions\UnknownItemException;
use OCA\Social\Exceptions\UrlCloudException;
use OCA\Social\Model\ActivityPub\ACore;
use OCA\Social\Service\ActivityPub\FollowService;
use OCA\Social\Service\ActivityPub\PersonService;
use OCA\Social\Service\ActivityService;
use OCA\Social\Service\ActorService;
use OCA\Social\Service\CacheActorService;
use OCA\Social\Service\FollowService;
use OCA\Social\Service\ImportService;
@ -166,7 +179,9 @@ class ActivityPubController extends Controller {
$origin = $this->signatureService->checkRequest($this->request);
$activity = $this->importService->importFromJson($body);
$activity->setOrigin($origin);
if (!$this->activityService->checkObject($activity)) {
$activity->setOrigin($origin);
}
try {
$this->importService->parseIncomingRequest($activity);
@ -205,7 +220,10 @@ class ActivityPubController extends Controller {
// $actor = $this->actorService->getActor($username);
$activity = $this->importService->importFromJson($body);
$activity->setOrigin($origin);
if (!$this->activityService->checkObject($activity)) {
$activity->setOrigin($origin);
}
try {
$this->importService->parseIncomingRequest($activity);
} catch (UnknownItemException $e) {

Wyświetl plik

@ -163,11 +163,8 @@ class LocalController extends Controller {
/**
* Create a new post.
* Delete your own post.
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -193,9 +190,6 @@ class LocalController extends Controller {
/**
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -216,10 +210,32 @@ class LocalController extends Controller {
}
/**
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
* @param int $since
* @param int $limit
*
* @return DataResponse
*/
public function streamNotifications($since = 0, int $limit = 5): DataResponse {
try {
$this->initViewer(true);
$posts = $this->noteService->getStreamNotifications($this->viewer, $since, $limit);
return $this->success($posts);
} catch (Exception $e) {
return $this->fail($e);
}
}
/**
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -244,9 +260,6 @@ class LocalController extends Controller {
/**
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -270,9 +283,6 @@ class LocalController extends Controller {
/**
* Get timeline
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -294,9 +304,6 @@ class LocalController extends Controller {
/**
* Get timeline
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -317,10 +324,6 @@ class LocalController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -341,10 +344,6 @@ class LocalController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -365,10 +364,6 @@ class LocalController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -387,7 +382,6 @@ class LocalController extends Controller {
/**
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -408,7 +402,6 @@ class LocalController extends Controller {
/**
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -429,10 +422,6 @@ class LocalController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -454,7 +443,6 @@ class LocalController extends Controller {
/**
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -477,7 +465,6 @@ class LocalController extends Controller {
/**
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -501,10 +488,6 @@ class LocalController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -526,10 +509,6 @@ class LocalController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -549,7 +528,6 @@ class LocalController extends Controller {
}
/**
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -578,10 +556,6 @@ class LocalController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -620,9 +594,6 @@ class LocalController extends Controller {
/**
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*

Wyświetl plik

@ -147,6 +147,7 @@ class NavigationController extends Controller {
try {
$data['serverData']['cloudAddress'] = $this->configService->getCloudAddress();
} catch (SocialAppConfigException $e) {
$this->checkService->checkInstallationStatus();
$cloudAddress = $this->setupCloudAddress();
if ($cloudAddress !== '') {
$data['serverData']['cloudAddress'] = $cloudAddress;
@ -221,8 +222,6 @@ class NavigationController extends Controller {
*
* @NoCSRFRequired
* @PublicPage
* @NoAdminRequired
* @NoSubAdminRequired
*
* @return DataResponse
*/
@ -278,10 +277,6 @@ class NavigationController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
@ -302,13 +297,8 @@ class NavigationController extends Controller {
/**
*
* // TODO: Delete the NoCSRF check
*
* @PublicPage
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
* @param string $id
*

Wyświetl plik

@ -86,12 +86,8 @@ class QueueController extends Controller {
/**
* // TODO: Delete the NoCSRF check
*
* @PublicPage
* @NoCSRFRequired
* @NoAdminRequired
* @NoSubAdminRequired
*
* @param string $token
*/

Wyświetl plik

@ -143,6 +143,20 @@ class FollowsRequest extends FollowsRequestBuilder {
}
/**
* @return int
*/
public function countFollows() {
$qb = $this->countFollowsSelectSql();
$cursor = $qb->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
return $this->getInt('count', $data, 0);
}
/**
* @param string $followId
*

Wyświetl plik

@ -133,7 +133,7 @@ class NotesRequest extends NotesRequestBuilder {
$cursor->closeCursor();
if ($data === false) {
throw new NoteNotFoundException();
throw new NoteNotFoundException('Post not found');
}
return $this->parseNotesSelectSql($data);
@ -186,10 +186,42 @@ class NotesRequest extends NotesRequestBuilder {
}
/**
* Should returns:
* * Public/Unlisted/Followers-only post where current $actor is tagged,
* - Events: (not yet)
* - people liking or re-posting your posts (not yet)
* - someone wants to follow you (not yet)
* - someone is following you (not yet)
*
* @param Person $actor
* @param int $since
* @param int $limit
*
* @return array
*/
public function getStreamNotifications(Person $actor, int $since = 0, int $limit = 5): array {
$qb = $this->getNotesSelectSql();
$this->limitPaginate($qb, $since, $limit);
$this->limitToRecipient($qb, $actor->getId(), false);
$this->leftJoinCacheActors($qb, 'attributed_to');
$notes = [];
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$notes[] = $this->parseNotesSelectSql($data);
}
$cursor->closeCursor();
return $notes;
}
/**
* Should returns:
* * public message from actorId.
* - to followers-only if follower is logged.
* - to followers-only if follower is logged. (not yet (check ?))
*
* @param string $actorId
* @param int $since
@ -218,7 +250,7 @@ class NotesRequest extends NotesRequestBuilder {
/**
* Should returns:
* * Private message.
* - group messages.
* - group messages. (not yet)
*
* @param Person $actor
* @param int $since
@ -249,7 +281,7 @@ class NotesRequest extends NotesRequestBuilder {
/**
* Should returns:
* - All local public/federated posts
* * All local public/federated posts
*
* @param int $since
* @param int $limit
@ -266,7 +298,7 @@ class NotesRequest extends NotesRequestBuilder {
}
$this->leftJoinCacheActors($qb, 'attributed_to');
// TODO: to: = real public, cc: = unlisted !?
$this->limitToRecipient($qb, ActivityService::TO_PUBLIC);
$this->limitToRecipient($qb, ActivityService::TO_PUBLIC, true, ['to']);
$notes = [];
$cursor = $qb->execute();

Wyświetl plik

@ -138,7 +138,7 @@ class NotesRequestBuilder extends CoreRequestBuilder {
$pf = $this->defaultSelectAlias . '.';
$on = $expr->orX();
$on->add($this->exprLimitToRecipient($qb, $actor->getFollowers(), true));
$on->add($this->exprLimitToRecipient($qb, $actor->getFollowers(), false));
// list of possible recipient as a follower (to, to_array, cc, ...)
$recipientFields = $expr->orX();
@ -230,11 +230,12 @@ class NotesRequestBuilder extends CoreRequestBuilder {
* @param IQueryBuilder $qb
* @param string $recipient
* @param bool $asAuthor
* @param array $type
*/
protected function limitToRecipient(
IQueryBuilder &$qb, string $recipient, bool $asAuthor = false
IQueryBuilder &$qb, string $recipient, bool $asAuthor = false, array $type = []
) {
$qb->andWhere($this->exprLimitToRecipient($qb, $recipient, $asAuthor));
$qb->andWhere($this->exprLimitToRecipient($qb, $recipient, $asAuthor, $type));
}
@ -242,11 +243,12 @@ class NotesRequestBuilder extends CoreRequestBuilder {
* @param IQueryBuilder $qb
* @param string $recipient
* @param bool $asAuthor
* @param array $type
*
* @return ICompositeExpression
*/
protected function exprLimitToRecipient(
IQueryBuilder &$qb, string $recipient, bool $asAuthor = false
IQueryBuilder &$qb, string $recipient, bool $asAuthor = false, array $type = []
): ICompositeExpression {
$expr = $qb->expr();
@ -262,15 +264,42 @@ class NotesRequestBuilder extends CoreRequestBuilder {
);
}
$limit->add($expr->eq('to', $qb->createNamedParameter($recipient)));
$limit->add($this->exprValueWithinJsonFormat($qb, 'to_array', $recipient));
$limit->add($this->exprValueWithinJsonFormat($qb, 'cc', $recipient));
$limit->add($this->exprValueWithinJsonFormat($qb, 'bcc', $recipient));
if ($type === []) {
$type = ['to', 'cc', 'bcc'];
}
$this->addLimitToRecipient($qb, $limit, $type, $recipient);
return $limit;
}
/**
* @param IQueryBuilder $qb
* @param ICompositeExpression $limit
* @param array $type
* @param string $to
*/
private function addLimitToRecipient(
IQueryBuilder $qb, ICompositeExpression &$limit, array $type, string $to
) {
$expr = $qb->expr();
if (in_array('to', $type)) {
$limit->add($expr->eq('to', $qb->createNamedParameter($to)));
$limit->add($this->exprValueWithinJsonFormat($qb, 'to_array', $to));
}
if (in_array('cc', $type)) {
$limit->add($this->exprValueWithinJsonFormat($qb, 'cc', $to));
}
if (in_array('bcc', $type)) {
$limit->add($this->exprValueWithinJsonFormat($qb, 'bcc', $to));
}
}
/**
* @param IQueryBuilder $qb
* @param string $recipient

Wyświetl plik

@ -0,0 +1,8 @@
<?php
namespace OCA\Social\Exceptions;
class LinkedDataSignatureMissingException extends \Exception {
}

Wyświetl plik

@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
/**
* Nextcloud - Social Support
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Social\Migration;
use OCA\Social\Service\CheckService;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
/**
* Class CheckInstallation
*
* @package OCA\Social\Migration
*/
class CheckInstallation implements IRepairStep {
/** @var CheckService */
protected $checkService;
/**
* CheckInstallation constructor.
*
* @param CheckService $checkService
*/
public function __construct(CheckService $checkService) {
$this->checkService = $checkService;
}
/**
* Returns the step's name
*
* @return string
* @since 9.1.0
*/
public function getName() {
return 'Check the installation of the Social app.';
}
/**
* @param IOutput $output
*/
public function run(IOutput $output) {
$this->checkService->checkInstallationStatus();
}
}

Wyświetl plik

@ -37,6 +37,8 @@ use OCA\Social\Exceptions\ActivityCantBeVerifiedException;
use OCA\Social\Exceptions\InvalidOriginException;
use OCA\Social\Exceptions\InvalidResourceEntryException;
use OCA\Social\Exceptions\UrlCloudException;
use OCA\Social\Model\LinkedDataSignature;
use OCA\Social\Service\ActivityPub\ICoreService;
use OCA\Social\Model\ActivityPub\Object\Document;
@ -72,6 +74,10 @@ class ACore extends Item implements JsonSerializable {
private $icon = null;
/** @var LinkedDataSignature */
private $signature = null;
/**
* Core constructor.
*
@ -165,14 +171,45 @@ class ACore extends Item implements JsonSerializable {
}
/**
* @return bool
*/
public function gotSignature(): bool {
return ($this->signature !== null);
}
/**
* @return LinkedDataSignature
*/
public function getSignature(): LinkedDataSignature {
return $this->signature;
}
/**
* @param LinkedDataSignature $signature
*
* @return ACore
*/
public function setSignature(LinkedDataSignature $signature): Acore {
$this->signature = $signature;
return $this;
}
/**
* @param string $base
* @param bool $root
*
* @throws UrlCloudException
*/
public function generateUniqueId(string $base = '') {
if ($this->getUrlCloud() === '') {
throw new UrlCloudException();
public function generateUniqueId(string $base = '', bool $root = true) {
$url = '';
if ($root) {
$url = $this->getUrlCloud();
if ($url === '') {
throw new UrlCloudException();
}
}
if ($base !== '') {
@ -185,7 +222,7 @@ class ACore extends Item implements JsonSerializable {
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
$this->setId($this->getUrlCloud() . $base . '/' . $uuid);
$this->setId($url . $base . '/' . $uuid);
}
@ -490,13 +527,21 @@ class ACore extends Item implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
if ($this->gotSignature()) {
$this->entries['signature'] = $this->getSignature();
}
if ($this->isRoot()) {
$this->addEntryArray(
'@context', [
self::CONTEXT_ACTIVITYSTREAMS,
self::CONTEXT_SECURITY
]
);
$context = [self::CONTEXT_ACTIVITYSTREAMS];
if ($this->gotObject()
&& $this->getObject()
->gotSignature()) {
array_push($context, self::CONTEXT_SECURITY);
}
$this->addEntryArray('@context', $context);
}
$this->addEntry('id', $this->getId());
@ -523,7 +568,6 @@ class ACore extends Item implements JsonSerializable {
$this->addEntry('published', $this->getPublished());
$this->addEntryArray('tag', $this->getTags());
// $arr = $this->getEntries();
if ($this->gotObject()) {
$this->addEntryItem('object', $this->getObject());
} else {

Wyświetl plik

@ -71,11 +71,7 @@ class Accept extends ACore implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
]
);
return parent::jsonSerialize();
}
}

Wyświetl plik

@ -70,11 +70,7 @@ class Create extends ACore implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
]
);
return parent::jsonSerialize();
}
}

Wyświetl plik

@ -71,11 +71,7 @@ class Delete extends ACore implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
]
);
return parent::jsonSerialize();
}
}

Wyświetl plik

@ -126,13 +126,19 @@ class Follow extends ACore implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
'follow_id' => $this->getFollowId(),
'accepted' => $this->isAccepted()
]
);
$result = parent::jsonSerialize();
if ($this->isCompleteDetails()) {
array_merge(
$result,
[
'follow_id' => $this->getFollowId(),
'accepted' => $this->isAccepted()
]
);
}
return $result;
}
}

Wyświetl plik

@ -71,11 +71,7 @@ class Reject extends ACore implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
]
);
return parent::jsonSerialize();
}
}

Wyświetl plik

@ -70,11 +70,7 @@ class Undo extends ACore implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
]
);
return parent::jsonSerialize();
}
}

Wyświetl plik

@ -75,11 +75,7 @@ class Image extends Document implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
]
);
return parent::jsonSerialize();
}
}

Wyświetl plik

@ -35,6 +35,7 @@ use JsonSerializable;
use OCA\Social\Model\ActivityPub\ACore;
use OCA\Social\Service\ActivityService;
class Note extends ACore implements JsonSerializable {

Wyświetl plik

@ -71,11 +71,7 @@ class Tombstone extends ACore implements JsonSerializable {
* @return array
*/
public function jsonSerialize(): array {
return array_merge(
parent::jsonSerialize(),
[
]
);
return parent::jsonSerialize();
}
}

Wyświetl plik

@ -0,0 +1,318 @@
<?php
declare(strict_types=1);
/**
* Nextcloud - Social Support
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Social\Model;
use daita\MySmallPhpTools\Traits\TArrayTools;
use JsonSerializable;
use OCA\Social\Exceptions\LinkedDataSignatureMissingException;
use OCA\Social\Model\ActivityPub\ACore;
/**
* Class InstancePath
*
* @package OCA\Social\Model
*/
class LinkedDataSignature implements JsonSerializable {
use TArrayTools;
/** @var string */
private $type = '';
/** @var string */
private $creator = '';
/** @var string */
private $created = '';
/** @var string */
private $signatureValue = '';
/** @var string */
private $privateKey = '';
/** @var string */
private $publicKey = '';
/** @var array */
private $object = [];
/**
* LinkedDataSignature constructor.
*/
public function __construct() {
}
/**
* @return string
*/
public function getType(): string {
return $this->type;
}
/**
* @param string $type
*
* @return LinkedDataSignature
*/
public function setType(string $type): LinkedDataSignature {
$this->type = $type;
return $this;
}
/**
* @return string
*/
public function getCreator(): string {
return $this->creator;
}
/**
* @param string $creator
*
* @return LinkedDataSignature
*/
public function setCreator(string $creator): LinkedDataSignature {
$this->creator = $creator;
return $this;
}
/**
* @return string
*/
public function getCreated(): string {
return $this->created;
}
/**
* @param string $created
*
* @return LinkedDataSignature
*/
public function setCreated(string $created): LinkedDataSignature {
$this->created = $created;
return $this;
}
/**
* @return string
*/
public function getSignatureValue(): string {
return $this->signatureValue;
}
/**
* @param string $signatureValue
*
* @return LinkedDataSignature
*/
public function setSignatureValue(string $signatureValue): LinkedDataSignature {
$this->signatureValue = $signatureValue;
return $this;
}
/**
* @return array
*/
public function getObject(): array {
return $this->object;
}
/**
* @param array $object
*
* @return LinkedDataSignature
*/
public function setObject(array $object): LinkedDataSignature {
$this->object = $object;
return $this;
}
/**
* @return string
*/
public function getPrivateKey(): string {
return $this->privateKey;
}
/**
* @param string $privateKey
*
* @return LinkedDataSignature
*/
public function setPrivateKey(string $privateKey): LinkedDataSignature {
$this->privateKey = $privateKey;
return $this;
}
/**
* @return string
*/
public function getPublicKey(): string {
return $this->publicKey;
}
/**
* @param string $publicKey
*
* @return LinkedDataSignature
*/
public function setPublicKey(string $publicKey): LinkedDataSignature {
$this->publicKey = $publicKey;
return $this;
}
/**
* @throws LinkedDataSignatureMissingException
*/
public function sign() {
$header = [
'@context' => 'https://w3id.org/identity/v1',
'creator' => $this->getCreator(),
'created' => $this->getCreated()
];
$hash = $this->hashedCanonicalize($header) . $this->hashedCanonicalize($this->getObject());
$algo = OPENSSL_ALGO_SHA256;
if ($this->getType() === 'RsaSignature2017') {
$algo = OPENSSL_ALGO_SHA256;
}
if (!openssl_sign($hash, $signed, $this->getPrivateKey(), $algo)) {
throw new LinkedDataSignatureMissingException();
}
$this->setSignatureValue(base64_encode($signed));
}
/**
* @return bool
*/
public function verify(): bool {
$header = [
'@context' => 'https://w3id.org/identity/v1',
'creator' => $this->getCreator(),
'created' => $this->getCreated()
];
$hash = $this->hashedCanonicalize($header) . $this->hashedCanonicalize($this->getObject());
$signed = base64_decode($this->getSignatureValue());
$algo = OPENSSL_ALGO_SHA256;
if ($this->getType() === 'RsaSignature2017') {
$algo = OPENSSL_ALGO_SHA256;
}
if (openssl_verify($hash, $signed, $this->getPublicKey(), $algo) === 1) {
return true;
}
return false;
}
/**
* @param array $data
*
* @return string
*/
private function hashedCanonicalize(array $data): string {
$object = json_decode(json_encode($data), false);
$res = jsonld_normalize(
$object,
[
'algorithm' => 'URDNA2015',
'format' => 'application/nquads'
]
);
return hash('sha256', $res);
}
/**
* @param array $data
*
* @throws LinkedDataSignatureMissingException
*/
public function import(array $data) {
if (!in_array(ACore::CONTEXT_SECURITY, $this->getArray('@context', $data, []))) {
throw new LinkedDataSignatureMissingException();
}
$signature = $this->getArray('signature', $data, []);
if ($signature === []) {
throw new LinkedDataSignatureMissingException();
}
$this->setType($this->get('type', $signature, ''));
$this->setCreator($this->get('creator', $signature, ''));
$this->setCreated($this->get('created', $signature, ''));
$this->setSignatureValue($this->get('signatureValue', $signature, ''));
unset($data['signature']);
$this->setObject($data);
}
/**
* @return array
*/
public function jsonSerialize(): array {
return [
'type' => $this->getType(),
'creator' => $this->getCreator(),
'created' => $this->getCreated(),
'signatureValue' => $this->getSignatureValue()
];
}
}

Wyświetl plik

@ -39,6 +39,7 @@ use OCA\Social\Db\NotesRequest;
use OCA\Social\Exceptions\ActorDoesNotExistException;
use OCA\Social\Exceptions\EmptyQueueException;
use OCA\Social\Exceptions\InvalidResourceException;
use OCA\Social\Exceptions\LinkedDataSignatureMissingException;
use OCA\Social\Exceptions\NoHighPriorityRequestException;
use OCA\Social\Exceptions\QueueStatusException;
use OCA\Social\Exceptions\Request410Exception;
@ -51,6 +52,7 @@ use OCA\Social\Model\ActivityPub\Activity\Delete;
use OCA\Social\Model\ActivityPub\Actor\Person;
use OCA\Social\Model\ActivityPub\Object\Tombstone;
use OCA\Social\Model\InstancePath;
use OCA\Social\Model\LinkedDataSignature;
use OCA\Social\Model\RequestQueue;
class ActivityService {
@ -65,9 +67,6 @@ class ActivityService {
const TIMEOUT_ASYNC = 5;
const TIMEOUT_SERVICE = 10;
const CONTEXT_ACTIVITYSTREAMS = 'https://www.w3.org/ns/activitystreams';
const CONTEXT_SECURITY = 'https://w3id.org/security/v1';
const TO_PUBLIC = 'https://www.w3.org/ns/activitystreams#Public';
const DATE_FORMAT = 'D, d M Y H:i:s T';
@ -137,6 +136,7 @@ class ActivityService {
public function createActivity(Person $actor, ACore $item, ACore &$activity = null): string {
$activity = new Create();
$item->setParent($activity);
// $this->activityStreamsService->initCore($activity);
@ -151,6 +151,7 @@ class ActivityService {
// }
$activity->setActor($actor);
$this->signObject($actor, $activity);
return $this->request($activity);
}
@ -393,6 +394,96 @@ class ActivityService {
/**
* @param IRequest $request
*
* @return string
* @throws InvalidResourceException
* @throws MalformedArrayException
* @throws RequestException
* @throws SignatureException
* @throws SocialAppConfigException
* @throws UrlCloudException
* @throws SignatureIsGoneException
* @throws InvalidOriginException
*/
public function checkRequest(IRequest $request): string {
// TODO : check host is our current host.
// $host = $request->getHeader('host');
// if ($host === '') {
// throw new SignatureException('host is not set');
// }
$dTime = new DateTime($request->getHeader('date'));
$dTime->format(self::DATE_FORMAT);
if ($dTime->getTimestamp() < (time() - self::DATE_DELAY)) {
throw new SignatureException('object is too old');
}
try {
$origin = $this->checkSignature($request);
} catch (Request410Exception $e) {
throw new SignatureIsGoneException();
}
return $origin;
}
/**
* @param Person $actor
* @param ACore $object
*/
public function signObject(Person $actor, ACore &$object) {
$signature = new LinkedDataSignature();
$signature->setPrivateKey($actor->getPrivateKey());
$signature->setType('RsaSignature2017');
$signature->setCreator($actor->getId() . '#main-key');
$signature->setCreated($object->getPublished());
$signature->setObject(json_decode(json_encode($object), true));
try {
$signature->sign();
$object->setSignature($signature);
} catch (LinkedDataSignatureMissingException $e) {
}
}
/**
* @param ACore $object
*
* @return bool
* @throws InvalidResourceException
* @throws Request410Exception
* @throws RequestException
* @throws SocialAppConfigException
* @throws UrlCloudException
* @throws InvalidOriginException
*/
public function checkObject(ACore $object): bool {
try {
$actorId = $object->getActorId();
$signature = new LinkedDataSignature();
$signature->import(json_decode($object->getSource(), true));
$signature->setPublicKey($this->retrieveKey($actorId));
if ($signature->verify()) {
$object->setOrigin($this->getKeyOrigin($actorId));
return true;
}
} catch (LinkedDataSignatureMissingException $e) {
}
return false;
}
/**
* $signature = new LinkedDataSignature();
* @param ACore $activity
*
* @return string

Wyświetl plik

@ -103,7 +103,6 @@ class CacheDocumentService {
$content = $this->retrieveContent($url);
// TODO - get mime type in a better way.
// To get the mime type, we create a temp file
$tmpFile = tmpfile();
$tmpPath = stream_get_meta_data($tmpFile)['uri'];

Wyświetl plik

@ -24,6 +24,9 @@
namespace OCA\Social\Service;
use daita\MySmallPhpTools\Traits\TStringTools;
use OCA\Social\Db\FollowsRequest;
use OCA\Social\Model\ActivityPub\Follow;
use OCP\AppFramework\Http;
use OCP\Http\Client\IClientService;
use OCP\ICache;
@ -31,25 +34,56 @@ use OCP\IConfig;
use OCP\IRequest;
use OCP\IURLGenerator;
/**
* Class CheckService
*
* @package OCA\Social\Service
*/
class CheckService {
use TStringTools;
private $cache;
private $config;
private $clientService;
private $request;
private $urlGenerator;
/** @var FollowsRequest */
private $followRequest;
const CACHE_PREFIX = 'social_check_';
public function __construct(ICache $cache, IConfig $config, IClientService $clientService, IRequest $request, IURLGenerator $urlGenerator) {
/**
* CheckService constructor.
*
* @param ICache $cache
* @param IConfig $config
* @param IClientService $clientService
* @param IRequest $request
* @param IURLGenerator $urlGenerator
* @param FollowsRequest $followRequest
*/
public function __construct(
ICache $cache, IConfig $config, IClientService $clientService, IRequest $request,
IURLGenerator $urlGenerator, FollowsRequest $followRequest
) {
$this->cache = $cache;
$this->config = $config;
$this->clientService = $clientService;
$this->request = $request;
$this->urlGenerator = $urlGenerator;
$this->followRequest = $followRequest;
}
/**
* @return array
*/
public function checkDefault(): array {
$checks = [];
$checks['wellknown'] = $this->checkWellKnown();
@ -60,13 +94,19 @@ class CheckService {
$success = false;
}
}
return [
'success' => $success,
'checks' => $checks
'checks' => $checks
];
}
/**
* @return bool
*/
public function checkWellKnown(): bool {
$state = (bool) ($this->cache->get(self::CACHE_PREFIX . 'wellknown') === 'true');
$state = (bool)($this->cache->get(self::CACHE_PREFIX . 'wellknown') === 'true');
if ($state === true) {
return true;
}
@ -77,7 +117,9 @@ class CheckService {
return true;
}
if ($this->requestWellKnown($this->request->getServerProtocol() . '://' . $this->request->getServerHost())) {
if ($this->requestWellKnown(
$this->request->getServerProtocol() . '://' . $this->request->getServerHost()
)) {
return true;
}
@ -88,17 +130,50 @@ class CheckService {
return false;
}
private function requestWellKnown($base) {
/**
*
*/
public function checkInstallationStatus() {
$this->checkStatusTableFollows();
}
public function checkStatusTableFollows() {
if ($this->followRequest->countFollows() > 0) {
return;
}
$follow = new Follow();
$follow->setId($this->uuid());
$follow->setType('Unknown');
$follow->setActorId($this->uuid());
$follow->setObjectId($this->uuid());
$follow->setFollowId($this->uuid());
$this->followRequest->save($follow);
}
/**
* @param string $base
*
* @return bool
*/
private function requestWellKnown(string $base) {
try {
$url = $base . '/.well-known/webfinger';
$response = $this->clientService->newClient()->get($url);
$response = $this->clientService->newClient()
->get($url);
if ($response->getStatusCode() === Http::STATUS_OK) {
$this->cache->set(self::CACHE_PREFIX . 'wellknown', 'true', 3600);
return true;
}
} catch (\GuzzleHttp\Exception\ClientException $e) {
} catch (\Exception $e) {
}
return false;
}

Wyświetl plik

@ -39,6 +39,20 @@ use OCA\Social\Exceptions\RedundancyLimitException;
use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Exceptions\UnknownItemException;
use OCA\Social\Model\ActivityPub\ACore;
use OCA\Social\Model\ActivityPub\Activity\Accept;
use OCA\Social\Model\ActivityPub\Activity\Create;
use OCA\Social\Model\ActivityPub\Activity\Delete;
use OCA\Social\Model\ActivityPub\Activity\Reject;
use OCA\Social\Model\ActivityPub\Tombstone;
use OCA\Social\Model\ActivityPub\Document;
use OCA\Social\Model\ActivityPub\Follow;
use OCA\Social\Model\ActivityPub\Image;
use OCA\Social\Model\ActivityPub\Note;
use OCA\Social\Model\ActivityPub\Activity\Undo;
use OCA\Social\Service\ActivityPub\DeleteService;
use OCA\Social\Service\ActivityPub\FollowService;
use OCA\Social\Service\ActivityPub\NoteService;
use OCA\Social\Service\ActivityPub\UndoService;
class ImportService {
@ -70,10 +84,14 @@ class ImportService {
* @param string $json
*
* @return ACore
* @throws ActivityPubFormatException
* @throws InvalidResourceEntryException
* @throws SocialAppConfigException
* @throws UnknownItemException
* @throws SocialAppConfigException
* @throws ActivityPubFormatException
* @throws RedundancyLimitException
* @throws UrlCloudException
*/
public function importFromJson(string $json): ACore {
$data = json_decode($json, true);

Wyświetl plik

@ -30,14 +30,21 @@ declare(strict_types=1);
namespace OCA\Social\Service;
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
use Exception;
use OC\User\NoUserException;
use OCA\Social\Db\NotesRequest;
use OCA\Social\Exceptions\AccountAlreadyExistsException;
use OCA\Social\Exceptions\ActorDoesNotExistException;
use OCA\Social\Exceptions\InvalidOriginException;
use OCA\Social\Exceptions\NoteNotFoundException;
use OCA\Social\Exceptions\RedundancyLimitException;
use OCA\Social\Exceptions\SocialAppConfigException;
use OCA\Social\Exceptions\UnknownItemException;
use OCA\Social\Exceptions\UrlCloudException;
use OCA\Social\Exceptions\InvalidResourceException;
use OCA\Social\Exceptions\Request410Exception;
use OCA\Social\Exceptions\RequestException;
use OCA\Social\Model\ActivityPub\Actor\Person;
use OCA\Social\Model\ActivityPub\Object\Note;
use OCA\Social\Model\InstancePath;
@ -79,12 +86,9 @@ class NoteService {
* @param MiscService $miscService
*/
public function __construct(
NotesRequest $notesRequest,
ActivityService $activityService,
AccountService $accountService,
CacheActorService $cacheActorService,
ConfigService $configService,
MiscService $miscService
NotesRequest $notesRequest, ActivityService $activityService,
AccountService $accountService, CacheActorService $cacheActorService,
ConfigService $configService, MiscService $miscService
) {
$this->notesRequest = $notesRequest;
$this->activityService = $activityService;
@ -241,16 +245,29 @@ class NoteService {
/**
* @param Note $note
* @param string $replyTo
*
* @throws InvalidOriginException
* @throws InvalidResourceException
* @throws MalformedArrayException
* @throws NoteNotFoundException
* @throws RedundancyLimitException
* @throws Request410Exception
* @throws RequestException
* @throws SocialAppConfigException
* @throws UnknownItemException
*/
public function replyTo(Note $note, string $replyTo) {
if ($replyTo === '') {
return;
}
$author = $this->getAuthorFromPostId($replyTo);
$note->setInReplyTo($replyTo);
// TODO - type can be NOT public !
$note->addInstancePath(
new InstancePath($replyTo, InstancePath::TYPE_PUBLIC, InstancePath::PRIORITY_HIGH)
new InstancePath(
$author->getSharedInbox(), InstancePath::TYPE_INBOX, InstancePath::PRIORITY_HIGH
)
);
}
@ -294,6 +311,18 @@ class NoteService {
}
/**
* @param Person $actor
* @param int $since
* @param int $limit
*
* @return Note[]
*/
public function getStreamNotifications(Person $actor, int $since = 0, int $limit = 5): array {
return $this->notesRequest->getStreamNotifications($actor, $since, $limit);
}
/**
* @param string $actorId
* @param int $since
@ -352,5 +381,25 @@ class NoteService {
}
/**
* @param $noteId
*
* @return Person
* @throws InvalidResourceException
* @throws MalformedArrayException
* @throws NoteNotFoundException
* @throws Request410Exception
* @throws RequestException
* @throws SocialAppConfigException
* @throws InvalidOriginException
* @throws RedundancyLimitException
* @throws UnknownItemException
*/
public function getAuthorFromPostId($noteId) {
$note = $this->notesRequest->getNoteById($noteId);
return $this->cacheActorService->getFromId($note->getAttributedTo());
}
}

281
package-lock.json wygenerowano
Wyświetl plik

@ -14,25 +14,115 @@
}
},
"@babel/core": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.1.2.tgz",
"integrity": "sha512-IFeSSnjXdhDaoysIlev//UzHZbdEmm7D0EIH2qtse9xK7mXEZQpYjs2P00XlP1qYsYvid79p+Zgg6tz1mp6iVw==",
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.2.2.tgz",
"integrity": "sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.1.2",
"@babel/helpers": "^7.1.2",
"@babel/parser": "^7.1.2",
"@babel/template": "^7.1.2",
"@babel/traverse": "^7.1.0",
"@babel/types": "^7.1.2",
"@babel/generator": "^7.2.2",
"@babel/helpers": "^7.2.0",
"@babel/parser": "^7.2.2",
"@babel/template": "^7.2.2",
"@babel/traverse": "^7.2.2",
"@babel/types": "^7.2.2",
"convert-source-map": "^1.1.0",
"debug": "^3.1.0",
"json5": "^0.5.0",
"debug": "^4.1.0",
"json5": "^2.1.0",
"lodash": "^4.17.10",
"resolve": "^1.3.2",
"semver": "^5.4.1",
"source-map": "^0.5.0"
},
"dependencies": {
"@babel/generator": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz",
"integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==",
"dev": true,
"requires": {
"@babel/types": "^7.2.2",
"jsesc": "^2.5.1",
"lodash": "^4.17.10",
"source-map": "^0.5.0",
"trim-right": "^1.0.1"
}
},
"@babel/parser": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.2.tgz",
"integrity": "sha512-UNTmQ5cSLDeBGBl+s7JeowkqIHgmFAGBnLDdIzFmUNSuS5JF0XBcN59jsh/vJO/YjfsBqMxhMjoFGmNExmf0FA==",
"dev": true
},
"@babel/template": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz",
"integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/parser": "^7.2.2",
"@babel/types": "^7.2.2"
}
},
"@babel/traverse": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.2.tgz",
"integrity": "sha512-E5Bn9FSwHpSkUhthw/XEuvFZxIgrqb9M8cX8j5EUQtrUG5DQUy6bFyl7G7iQ1D1Czudor+xkmp81JbLVVM0Sjg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.2.2",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.0.0",
"@babel/parser": "^7.2.2",
"@babel/types": "^7.2.2",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.10"
}
},
"@babel/types": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz",
"integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.10",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
"integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"json5": {
"version": "2.1.0",
"resolved": "http://registry.npmjs.org/json5/-/json5-2.1.0.tgz",
"integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
}
}
},
"@babel/generator": {
@ -254,14 +344,78 @@
}
},
"@babel/helpers": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.1.2.tgz",
"integrity": "sha512-Myc3pUE8eswD73aWcartxB16K6CGmHDv9KxOmD2CeOs/FaEAQodr3VYGmlvOmog60vNQ2w8QbatuahepZwrHiA==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.2.0.tgz",
"integrity": "sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A==",
"dev": true,
"requires": {
"@babel/template": "^7.1.2",
"@babel/traverse": "^7.1.0",
"@babel/types": "^7.1.2"
"@babel/traverse": "^7.1.5",
"@babel/types": "^7.2.0"
},
"dependencies": {
"@babel/generator": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz",
"integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==",
"dev": true,
"requires": {
"@babel/types": "^7.2.2",
"jsesc": "^2.5.1",
"lodash": "^4.17.10",
"source-map": "^0.5.0",
"trim-right": "^1.0.1"
}
},
"@babel/parser": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.2.tgz",
"integrity": "sha512-UNTmQ5cSLDeBGBl+s7JeowkqIHgmFAGBnLDdIzFmUNSuS5JF0XBcN59jsh/vJO/YjfsBqMxhMjoFGmNExmf0FA==",
"dev": true
},
"@babel/traverse": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.2.tgz",
"integrity": "sha512-E5Bn9FSwHpSkUhthw/XEuvFZxIgrqb9M8cX8j5EUQtrUG5DQUy6bFyl7G7iQ1D1Czudor+xkmp81JbLVVM0Sjg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.2.2",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.0.0",
"@babel/parser": "^7.2.2",
"@babel/types": "^7.2.2",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.10"
}
},
"@babel/types": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz",
"integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.10",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
"integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
}
}
},
"@babel/highlight": {
@ -2643,6 +2797,12 @@
}
}
},
"clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
"dev": true
},
"clone-regexp": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.1.tgz",
@ -2987,9 +3147,9 @@
}
},
"css-loader": {
"version": "2.0.0",
"resolved": "http://registry.npmjs.org/css-loader/-/css-loader-2.0.0.tgz",
"integrity": "sha512-3Fq8HJYs7ruBiDpJA/w2ZROtivA769ePuH3/vgPdOB+FQiotErJ7VJYRZq86SPRVFaccn1wEktUnaaUyf+Uslw==",
"version": "2.0.1",
"resolved": "http://registry.npmjs.org/css-loader/-/css-loader-2.0.1.tgz",
"integrity": "sha512-XIVwoIOzSFRVsafOKa060GJ/A70c0IP/C1oVPHEX4eHIFF39z0Jl7j8Kua1SUTiqWDupUnbY3/yQx9r7EUB35w==",
"dev": true,
"requires": {
"icss-utils": "^4.0.0",
@ -3005,9 +3165,9 @@
},
"dependencies": {
"ajv": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz",
"integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==",
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz",
"integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
@ -3035,9 +3195,9 @@
"dev": true
},
"postcss": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz",
"integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==",
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"dev": true,
"requires": {
"chalk": "^2.4.1",
@ -4294,19 +4454,19 @@
}
},
"file-loader": {
"version": "1.1.11",
"resolved": "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
"integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==",
"version": "2.0.0",
"resolved": "http://registry.npmjs.org/file-loader/-/file-loader-2.0.0.tgz",
"integrity": "sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ==",
"dev": true,
"requires": {
"loader-utils": "^1.0.2",
"schema-utils": "^0.4.5"
"schema-utils": "^1.0.0"
},
"dependencies": {
"ajv": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz",
"integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==",
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz",
"integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
@ -4334,12 +4494,13 @@
"dev": true
},
"schema-utils": {
"version": "0.4.7",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
"integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
"integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
"dev": true,
"requires": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
}
}
@ -5453,9 +5614,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz",
"integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==",
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"dev": true,
"requires": {
"chalk": "^2.4.1",
@ -7388,14 +7549,6 @@
"requires": {
"clone": "2.x",
"lodash": "4.x"
},
"dependencies": {
"clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
"dev": true
}
}
},
"node-int64": {
@ -8058,9 +8211,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz",
"integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==",
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"dev": true,
"requires": {
"chalk": "^2.4.1",
@ -8088,9 +8241,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz",
"integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==",
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"dev": true,
"requires": {
"chalk": "^2.4.1",
@ -8117,9 +8270,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz",
"integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==",
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"dev": true,
"requires": {
"chalk": "^2.4.1",
@ -8146,9 +8299,9 @@
},
"dependencies": {
"postcss": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.6.tgz",
"integrity": "sha512-Nq/rNjnHFcKgCDDZYO0lNsl6YWe6U7tTy+ESN+PnLxebL8uBtYX59HZqvrj7YLK5UCyll2hqDsJOo3ndzEW8Ug==",
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
"integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
"dev": true,
"requires": {
"chalk": "^2.4.1",
@ -11771,9 +11924,9 @@
"integrity": "sha512-CKITl7I1cb3X4zIHbVSyrupPTs9XxZGVV/N+P5lSxSrGW+D92gq6zuTy/XnvJOwMRkjJuiotJAQrgv+gOwSx3g=="
},
"vue-jest": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.1.tgz",
"integrity": "sha512-otS+n341cTsp0pF7tuTu2x43b23x/+K0LZdAXV+ewKYIMZRqhuQaJTECWEt/cN/YZw2JC6hUM6xybdnOB4ZQ+g==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.2.tgz",
"integrity": "sha512-5XIQ1xQFW0ZnWxHWM7adVA2IqbDsdw1vhgZfGFX4oWd75J38KIS3YT41PtiE7lpMLmNM6+VJ0uprT2mhHjUgkA==",
"dev": true,
"requires": {
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
@ -12476,9 +12629,9 @@
}
},
"webpack-merge": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.4.tgz",
"integrity": "sha512-TmSe1HZKeOPey3oy1Ov2iS3guIZjWvMT2BBJDzzT5jScHTjVC3mpjJofgueEzaEd6ibhxRDD6MIblDr8tzh8iQ==",
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.5.tgz",
"integrity": "sha512-sVcM+MMJv6DO0C0GLLltx8mUlGMKXE0zBsuMqZ9jz2X9gsekALw6Rs0cAfTWc97VuWS6NpVUa78959zANnMMLQ==",
"dev": true,
"requires": {
"lodash": "^4.17.5"

Wyświetl plik

@ -54,14 +54,14 @@
"node": ">=10.0.0"
},
"devDependencies": {
"@babel/core": "^7.1.2",
"@babel/core": "^7.2.2",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@vue/test-utils": "^1.0.0-beta.27",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.4",
"css-loader": "^2.0.0",
"css-loader": "^2.0.1",
"eslint": "^4.19.1",
"eslint-config-standard": "^11.0.0",
"eslint-friendly-formatter": "^4.0.1",
@ -72,7 +72,7 @@
"eslint-plugin-standard": "^3.1.0",
"eslint-plugin-vue": "^4.5.0",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.11",
"file-loader": "^2.0.0",
"jest": "^23.6.0",
"jest-serializer-vue": "^2.0.2",
"mini-css-extract-plugin": "^0.5.0",
@ -81,13 +81,13 @@
"stylelint": "^8.4.0",
"stylelint-config-recommended-scss": "^3.2.0",
"stylelint-webpack-plugin": "^0.10.5",
"vue-jest": "^3.0.1",
"vue-jest": "^3.0.2",
"vue-loader": "^15.4.2",
"vue-style-loader": "^4.1.1",
"vue-template-compiler": "^2.5.21",
"webpack": "^4.27.1",
"webpack-cli": "^3.1.2",
"webpack-merge": "^4.1.2"
"webpack-merge": "^4.1.5"
},
"jest": {
"moduleFileExtensions": [