...
 
Commits (20)
<?php
namespace Minds\Controllers\Cli;
use Minds\Cli;
use Minds\Core\Events\Dispatcher;
use Minds\Interfaces;
class Notification extends Cli\Controller implements Interfaces\CliControllerInterface
{
public function help($command = null)
{
switch ($command) {
case 'send':
$this->out('Send a notification');
$this->out('--namespace=<type> Notification namespace');
$this->out('--to=<user guid> User to send notification to');
$this->out('--from=<entity guid> Entity notification is from (defaults to system user)');
$this->out('--view=<view> Notification view');
$this->out('--params=<params> JSON payload data');
// no break
default:
$this->out('Syntax usage: cli notification <cmd>');
$this->displayCommandHelp();
}
}
public function exec()
{
$this->help();
}
public function send()
{
$namespace = $this->getOpt('namespace');
$to = $this->getOpt('to');
$from = $this->getOpt('from') ?? \Minds\Core\Notification\Notification::SYSTEM_ENTITY;
$view = $this->getOpt('view');
$params = $this->getOpt('params') ?? '{}';
if (is_null($namespace)) {
$this->out('namespace must be set');
return;
}
if (is_null($to)) {
$this->out('to must be set');
return;
}
if (is_null($view)) {
$this->out('view must be set');
return;
}
$paramsDecoded = json_decode($params, true);
if (is_null($paramsDecoded)) {
$this->out('Params is not valid JSON');
return;
}
$eventParams = [
'to' => [$to],
'from' => $from,
'notification_view' => $view,
'params' => $paramsDecoded
];
$sent = Dispatcher::trigger('notification', $namespace, $eventParams);
if ($sent) {
$this->out('Notification sent');
} else {
$this->out('Error sending notification - is from guid valid?');
}
}
}
......@@ -31,7 +31,7 @@ class reports implements Interfaces\Api, Interfaces\ApiAdminPam
/** @var Core\Reports\Repository $repository */
$repository = Di::_()->get('Reports\Repository');
$reports = $repository->getAll([
$reports = $repository->getList([
'state' => $state,
'limit' => $limit,
'offset' => $offset
......
......@@ -344,14 +344,20 @@ class blog implements Interfaces\Api
}
if ($saved && is_uploaded_file($_FILES['file']['tmp_name'])) {
/** @var Core\Media\Imagick\Manager $manager */
$manager = Core\Di\Di::_()->get('Media\Imagick\Manager');
$manager->setImage($_FILES['file']['tmp_name'])
->resize(2000, 1000);
try {
$manager->setImage($_FILES['file']['tmp_name'])
->resize(2000, 1000);
$header->write($blog, $manager->getJpeg(), isset($_POST['header_top']) ? (int) $_POST['header_top'] : 0);
$header->write($blog, $manager->getJpeg(), isset($_POST['header_top']) ? (int)$_POST['header_top'] : 0);
} catch (\ImagickException $e) {
return Factory::response([
'status' => 'error',
'message' => 'Invalid image file',
]);
}
}
if ($saved) {
......
......@@ -13,6 +13,7 @@ use Minds\Helpers;
use Minds\Entities;
use Minds\Interfaces;
use Minds\Api\Factory;
use Minds\Core\Features\Manager as FeaturesManager;
class thumbnails implements Interfaces\Api, Interfaces\ApiIgnorePam
{
......@@ -28,6 +29,17 @@ class thumbnails implements Interfaces\Api, Interfaces\ApiIgnorePam
exit;
}
$featuresManager = new FeaturesManager();
if ($featuresManager->has('cdn-jwt')) {
error_log("{$_SERVER['REQUEST_URI']} was hit, and should not have been");
return Factory::response([
'status' => 'error',
'message' => 'This endpoint has been deprecated. Please use fs/v1/thumbnail',
]);
}
$guid = $pages[0];
Core\Security\ACL::$ignore = true;
......
......@@ -53,6 +53,7 @@ class views implements Interfaces\Api
$viewsManager->record(
(new Core\Analytics\Views\View())
->setEntityUrn($boost->getEntity()->getUrn())
->setOwnerGuid((string) $boost->getEntity()->getOwnerGuid())
->setClientMeta($_POST['client_meta'] ?? [])
);
} catch (\Exception $e) {
......@@ -105,6 +106,7 @@ class views implements Interfaces\Api
$viewsManager->record(
(new Core\Analytics\Views\View())
->setEntityUrn($activity->getUrn())
->setOwnerGuid((string) $activity->getOwnerGuid())
->setClientMeta($_POST['client_meta'] ?? [])
);
} catch (\Exception $e) {
......
......@@ -20,7 +20,14 @@ class connect implements Interfaces\Api
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
try {
$account = $connectManager->getByUser($user);
} catch (\Exception $e) {
return Factory::response([
'status' => 'error',
'message' => 'There was an error returning the usd account',
]);
}
return Factory::response([
'account' => $account->export(),
......
<?php
/**
*
*/
namespace Minds\Controllers\api\v2\payments\stripe\connect;
use Minds\Api\Factory;
use Minds\Common\Cookie;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class photoid implements Interfaces\Api
{
public function get($pages)
{
return Factory::response([]);
}
public function post($pages)
{
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
$fp = fopen($_FILES['file']['tmp_name'], 'r');
$connectManager->addPhotoId($account, $fp);
return Factory::response([ 'account_id' => $account->getId() ]);
}
public function put($pages)
{
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
<?php
/**
*
*/
namespace Minds\Controllers\api\v2\payments\stripe\connect;
use Minds\Api\Factory;
use Minds\Common\Cookie;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class terms implements Interfaces\Api
{
public function get($pages)
{
return Factory::response([]);
}
public function post($pages)
{
return Factory::response([]);
}
public function put($pages)
{
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
$account = $connectManager->getByUser($user);
$account->setIp($_SERVER['HTTP_X_FORWARDED_FOR']);
$connectManager->acceptTos($account);
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
<?php
/**
*
*/
namespace Minds\Controllers\api\v2\payments\stripe;
use Minds\Api\Factory;
use Minds\Common\Cookie;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Core\Session;
use Minds\Interfaces;
use Minds\Core\Payments\Stripe;
class transactions implements Interfaces\Api
{
public function get($pages)
{
$user = Session::getLoggedInUser();
$connectManager = new Stripe\Connect\Manager();
try {
$account = $connectManager->getByUser($user);
} catch (\Exception $e) {
return Factory::response([
'status' => 'error',
'message' => 'There was an error returning the usd account',
]);
}
$transactionsManger = new Stripe\Transactions\Manager();
$transactions = $transactionsManger->getByAccount($account);
return Factory::response([
'transactions' => Factory::exportable($transactions),
]);
}
public function post($pages)
{
return Factory::response([]);
}
public function put($pages)
{
return Factory::response([]);
}
public function delete($pages)
{
return Factory::response([]);
}
}
......@@ -8,6 +8,7 @@ use Minds\Interfaces;
use Minds\Core\Entities\Actions\Save;
use Minds\Core\Session;
use Minds\Core\Permissions\Permissions;
use Minds\Core\Permissions\Entities\EntityPermissions;
class comments implements Interfaces\Api
{
......
......@@ -8,6 +8,7 @@ use Minds\Core;
use Minds\Core\Di\Di;
use Minds\Entities;
use Minds\Interfaces;
use Minds\Core\Features\Manager as FeaturesManager;
class thumbnail extends Core\page implements Interfaces\page
{
......@@ -17,6 +18,16 @@ class thumbnail extends Core\page implements Interfaces\page
exit;
}
$featuresManager = new FeaturesManager;
if ($featuresManager->has('cdn-jwt')) {
$signedUri = new Core\Security\SignedUri();
$uri = (string) \Zend\Diactoros\ServerRequestFactory::fromGlobals()->getUri();
if (!$signedUri->confirm($uri)) {
exit;
}
}
/** @var Core\Media\Thumbnails $mediaThumbnails */
$mediaThumbnails = Di::_()->get('Media\Thumbnails');
......
......@@ -55,6 +55,7 @@ class ElasticRepository
'uuid' => $view->getUuid(),
'@timestamp' => $view->getTimestamp() * 1000,
'entity_urn' => $view->getEntityUrn(),
'owner_guid' => $view->getOwnerGuid(),
'page_token' => $view->getPageToken(),
'campaign' => $view->getCampaign(),
'delta' => (int) $view->getDelta(),
......
......@@ -104,6 +104,7 @@ class Repository
->setDay((int) $row['day'] ?: null)
->setUuid($row['uuid']->uuid() ?: null)
->setEntityUrn($row['entity_urn'])
->setOwnerGuid($row['owner_guid'])
->setPageToken($row['page_token'])
->setPosition((int) $row['position'])
->setSource($row['platform'])
......@@ -135,13 +136,14 @@ class Repository
$timestamp = $view->getTimestamp() ?: time();
$date = new DateTime("@{$timestamp}", new DateTimeZone('utc'));
$cql = "INSERT INTO views (year, month, day, uuid, entity_urn, page_token, position, platform, source, medium, campaign, delta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$cql = "INSERT INTO views (year, month, day, uuid, entity_urn, owner_guid, page_token, position, platform, source, medium, campaign, delta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$values = [
(int) ($view->getYear() ?? $date->format('Y')),
new Tinyint((int) ($view->getMonth() ?? $date->format('m'))),
new Tinyint((int) ($view->getDay() ?? $date->format('d'))),
new Timeuuid($view->getUuid() ?? $timestamp * 1000),
$view->getEntityUrn() ?: '',
(string) ($view->getOwnerGuid() ?? ''),
$view->getPageToken() ?: '',
(int) ($view->getPosition() ?? -1),
$view->getPlatform() ?: '',
......
......@@ -21,6 +21,8 @@ use Minds\Traits\MagicAttributes;
* @method string getUuid()
* @method View setEntityUrn(string $entityUrn)
* @method string getEntityUrn()
* @method View setOwnerGuid(string $ownerGuid)
* @method string getOwnerGuid()
* @method View setPageToken(string $pageToken)
* @method string getPageToken()
* @method View setPosition(int $position)
......@@ -57,6 +59,9 @@ class View
/** @var string */
protected $entityUrn;
/** @var string */
protected $ownerGuid;
/** @var string */
protected $pageToken;
......
......@@ -9,6 +9,7 @@ use Minds\Entities\RepositoryEntity;
use Minds\Entities\User;
use Minds\Helpers\Flags;
use Minds\Helpers\Unknown;
use Minds\Core\Di\Di;
/**
* Comment Entity
......@@ -284,6 +285,21 @@ class Comment extends RepositoryEntity
return "{$this->getParentGuidL1()}:{$this->getParentGuidL2()}:{$this->getGuid()}";
}
/**
* Return an array of thumbnails
* @return array
*/
public function getThumbnails(): array
{
$thumbnails = [];
$mediaManager = Di::_()->get('Media\Image\Manager');
$sizes = [ 'xlarge', 'large' ];
foreach ($sizes as $size) {
$thumbnails[$size] = $mediaManager->getPublicAssetUri($this, $size);
}
return $thumbnails;
}
/**
* Return the urn for the comment
* @return string
......@@ -384,6 +400,8 @@ class Comment extends RepositoryEntity
$output['thumbs:down:count'] = count($this->getVotesDown());
}
$output['thumbnails'] = $this->getThumbnails();
$output['can_reply'] = (bool) !$this->getParentGuidL2();
//$output['parent_guid'] = (string) $this->entityGuid;
......
......@@ -5,21 +5,40 @@
namespace Minds\Core\Data\PubSub\Redis;
use Minds\Core\Config;
use \Redis as RedisServer;
class Client
{
/**
* @var \Redis
*/
private $redis;
/**
* @var string
*/
private $host;
public function __construct($redis = null)
{
if (class_exists('\Redis')) {
$this->redis = $redis ?: new RedisServer();
$this->redis = $redis ?: new \Redis();
$config = Config::_()->get('redis');
try {
$this->redis->connect($config['pubsub'] ?: $config['master'] ?: '127.0.0.1');
} catch (\Exception $e) {
$this->host = $config['pubsub'] ?: $config['master'] ?: '127.0.0.1';
$this->connect();
}
}
/**
* @throws \Exception
*/
public function connect(): void
{
if (!$this->redis instanceof \Redis) {
$this->redis = new \Redis();
}
if (!$this->redis->isConnected()) {
if (!@$this->redis->connect($this->host)) {
throw new \Exception("Unable to connect to Redis: " . $this->redis->getLastError());
}
}
}
......@@ -34,11 +53,17 @@ class Client
}
}
/**
* @param $channel
* @param string $data
* @return bool|int
*/
public function publish($channel, $data = '')
{
if (!$this->redis) {
if (!$this->redis->isConnected()) {
return false;
}
return $this->redis->publish($channel, $data);
}
}
......@@ -16,7 +16,7 @@
</a>
</td>
<td style="width: 70%">
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>@<?php echo $vars['sender']->get('name'); ?> wired you</h4>
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>@<?php echo $vars['sender']->get('username'); ?> wired you</h4>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>Transfer Date and Amount:</p>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>
<?php echo $wireDate; ?>; +<?php echo $amount ?>
......
......@@ -16,7 +16,7 @@
</a>
</td>
<td style="width: 70%">
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>You wired @<?php echo $vars['receiver']->get('name'); ?></h4>
<h4 <?php echo $emailStyles->getStyles('m-clear', 'm-fonts', 'm-header'); ?>>You wired @<?php echo $vars['receiver']->get('username'); ?></h4>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>Transfer Date and Amount:</p>
<p <?php echo $emailStyles->getStyles('m-fonts', 'm-subtitle', 'm-clear'); ?>>
<?php echo $wireDate; ?>; +<?php echo $amount ?>
......
<?php
/**
* Image Manager
*/
namespace Minds\Core\Media\Image;
use Minds\Core\Config;
use Minds\Core\Di\Di;
use Minds\Core\Session;
use Minds\Entities\Entity;
use Minds\Entities\Activity;
use Minds\Entities\Image;
use Minds\Entities\Video;
use Minds\Core\Comments\Comment;
use Minds\Core\Security\SignedUri;
use Lcobucci\JWT;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Zend\Diactoros\Uri;
class Manager
{
/** @var Config $config */
private $config;
/** @var SignedUri $signedUri */
private $signedUri;
public function __construct($config = null, $signedUri = null)
{
$this->config = $config ?? Di::_()->get('Config');
$this->signedUri = $signedUri ?? new SignedUri;
}
/**
* Return a public asset uri for entity type
* @param Entity $entity
* @param string $size
* @return string
*/
public function getPublicAssetUri($entity, $size = 'xlarge'): string
{
$uri = null;
$asset_guid = null;
switch (get_class($entity)) {
case Activity::class:
switch ($entity->get('custom_type')) {
case "batch":
$asset_guid = $entity->get('entity_guid');
break;
default:
$asset_guid = $entity->get('entity_guid');
}
break;
case Image::class:
$asset_guid = $entity->getGuid();
break;
case Video::class:
$asset_guid = $entity->getGuid();
break;
case Comment::class:
$asset_guid = $entity->getAttachments()['attachment_guid'];
break;
}
$uri = $this->config->get('cdn_url') . 'fs/v1/thumbnail/' . $asset_guid . '/' . $size;
$uri = $this->signUri($uri);
return $uri;
}
/**
* Sign a uri and return the uri with the signature attached
* @param string $uri
* @return string
*/
private function signUri($uri, $pub = ""): string
{
$now = new \DateTime();
$expires = $now->modify('midnight + 30 days')->getTimestamp();
return $this->signedUri->sign($uri, $expires);
}
/**
* Config signed uri
* @param string $uri
* @return string
*/
public function confirmSignedUri($uri): bool
{
return $this->signedUri->confirm($uri);
}
}
......@@ -12,6 +12,12 @@ class MediaProvider extends Provider
{
public function register()
{
$this->di->bind('Media\Image\Manager', function ($di) {
return new Image\Manager();
}, ['useFactory' => true]);
$this->di->bind('Media\Video\Manager', function ($di) {
return new Video\Manager();
}, ['useFactory' => true]);
$this->di->bind('Media\Albums', function ($di) {
return new Albums(new Core\Data\Call('entities_by_time'));
}, ['useFactory' => true]);
......
<?php
/**
* Video Manager
*/
namespace Minds\Core\Media\Video;
use Minds\Core\Config;
use Minds\Core\Di\Di;
use Minds\Core\Session;
use Minds\Entities\Entity;
use Minds\Entities\Activity;
use Minds\Entities\Image;
use Minds\Entities\Video;
use Minds\Core\Comments\Comment;
use Aws\S3\S3Client;
class Manager
{
/** @var Config $config */
private $config;
/** @var S3Client $s3 */
private $s3;
public function __construct($config = null, $s3 = null)
{
$this->config = $config ?? Di::_()->get('Config');
// AWS
$awsConfig = $this->config->get('aws');
$opts = [
'region' => $awsConfig['region'],
];
if (!isset($awsConfig['useRoles']) || !$awsConfig['useRoles']) {
$opts['credentials'] = [
'key' => $awsConfig['key'],
'secret' => $awsConfig['secret'],
];
}
$this->s3 = $s3 ?: new S3Client(array_merge(['version' => '2006-03-01'], $opts));
}
/**
* Return a public asset uri for entity type
* @param Entity $entity
* @param string $size
* @return string
*/
public function getPublicAssetUri($entity, $size = '360.mp4'): string
{
$cmd = null;
switch (get_class($entity)) {
case Activity::class:
// To do
break;
case Video::class:
$cmd = $this->s3->getCommand('GetObject', [
'Bucket' => 'cinemr', // TODO: don't hard code
'Key' => $this->config->get('transcoder')['dir'] . "/" . $entity->get('cinemr_guid') . "/" . $size,
]);
break;
}
if (!$cmd) {
return null;
}
return (string) $this->s3->createPresignedRequest($cmd, '+20 minutes')->getUri();
}
}
......@@ -95,6 +95,24 @@ class Account
/** @var string $status */
private $status = "processing";
/** @var Balance $totalBalance */
private $totalBalance;
/** @var Balance $pendingBalance */
private $pendingBalance;
/** @var string $payoutInterval */
private $payoutInterval;
/** @var int $payoutDelay */
private $payoutDelay;
/** @var int $payoutAnchor */
private $payoutAnchor;
/** @var string $requirement */
private $requirement;
/** @var array $exportable */
private $exportable = [
'guid',
......@@ -118,6 +136,10 @@ class Account
'status',
'verified',
'bankAccount',
'payoutInterval',
'payoutDelay',
'payoutAnchor',
'requirement',
];
/**
......@@ -146,6 +168,14 @@ class Account
$export[$field] = $this->$field;
}
if ($this->totalBalance) {
$export['totalBalance'] = $this->totalBalance->export();
}
if ($this->pendingBalance) {
$export['pendingBalance'] = $this->pendingBalance->export();
}
return $export;
}
}
<?php
/**
* Stripe Connect Balance
*/
namespace Minds\Core\Payments\Stripe\Connect;
use Minds\Traits\MagicAttributes;
/**
* @method Balance getAmount(): int
* @method Balance getCurrency(): string
*/
class Balance
{
use MagicAttributes;
/** @var int $amount */
private $amount;
/** @var string $currency */
private $currency;
/**
* Expose to public API
* @return array
*/
public function export(array $extend = []) : array
{
return [
'amount' => (int) $this->amount,
'currency' => $this->currency,
];
}
}
......@@ -6,6 +6,8 @@ use Minds\Core\Entities\Actions\Save;
use Minds\Core\Payments\Stripe\Connect\Delegates\NotificationDelegate;
use Minds\Core\Payments\Stripe\Currencies;
use Minds\Core\Payments\Stripe\Instances\AccountInstance;
use Minds\Core\Payments\Stripe\Instances\BalanceInstance;
use Minds\Core\Payments\Stripe\Instances\FileInstance;
use Stripe;
use Minds\Entities\User;
......@@ -20,14 +22,24 @@ class Manager
/** @var AccountInstance $accountInstance */
private $accountInstance;
/** @var BalanceInstance $balanceInstance */
private $balanceInstance;
/** @var FileInstance $fileInstance */
private $fileInstance;
public function __construct(
Save $save = null,
NotificationDelegate $notificationDelegate = null,
AccountInstance $accountInstance = null
AccountInstance $accountInstance = null,
BalanceInstance $balanceInstance = null,
FileInstance $fileInstance = null
) {
$this->save = $save ?: new Save();
$this->notificationDelegate = $notificationDelegate ?: new NotificationDelegate();
$this->accountInstance = $accountInstance ?: new AccountInstance();
$this->balanceInstance = $balanceInstance ?: new BalanceInstance();
$this->fileInstance = $fileInstance ?: new FileInstance();
}
/**
......@@ -167,6 +179,27 @@ class Manager
return $stripeAccount->id;
}
/**
* Updates a stripe connect account
* @param $account
* @return bool
* @throws \Exception
*/
public function acceptTos(Account $account) : bool
{
try {
$this->accountInstance->update($account->getId(), [
'tos_acceptance' => [
'date' => time(),
'ip' => $account->getIp(),
],
]);
return true;
} catch (\Exception $e) {
return false;
}
}
/**
* Add a bank account to stripe account
* @param Account $account
......@@ -195,12 +228,26 @@ class Manager
return true;
}
/**
* Add photo Id
* @param Account $account
* @param resource $file
* @return bool
*/
public function addPhotoId(Account $account, $file) : bool
{
return (bool) $this->fileInstance->create([
'purpose' => 'identity_document',
'file' => $file,
], [ 'stripe_account' => $account->getId() ]);
}
/**
* Return a stripe account
* @param string $id
* @return Account
*/
public function getByAccountId(string $id) : Account
public function getByAccountId(string $id) : ?Account
{
try {
$result = $this->accountInstance->retrieve($id);
......@@ -223,20 +270,30 @@ class Manager
->setBankAccount($result->external_accounts->data[0])
->setAccountNumber($result->external_accounts->data[0]['last4'])
->setRoutingNumber($result->external_accounts->data[0]['routing_number'])
->setDestination('bank');
->setDestination('bank')
->setPayoutInterval($result->settings->payouts->schedule->interval)
->setPayoutDelay($result->settings->payouts->schedule->delay_days)
->setPayoutAnchor($result->settings->payouts->schedule->monthly_anchor);
//verifiction check
if ($result->legal_entity->verification->status === 'verified') {
$account->setVerified(true);
}
if ($result->verification->disabled_reason == 'fields_needed') {
if ($result->verification->fields_needed[0] == 'legal_entity.verification.document') {
$account->setStatus('awaiting-document');
if (!$account->getVerified()) {
switch ($result->requirements->disabled_reason) {
case 'requirements.past_due':
$account->setRequirement($result->requirements->currently_due[0]);
break;
}
}
$account->setTotalBalance($this->getBalanceById($result->id, 'available'));
$account->setPendingBalance($this->getBalanceById($result->id, 'pending'));
return $account;
} catch (Stripe\Error\Permission $e) {
throw new \Exception($e->getMessage());
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
......@@ -256,6 +313,20 @@ class Manager
return $this->getByAccountId($merchant['id']);
}
/**
* Get balance by ID
* @param string $id
* @return Balance
*/
public function getBalanceById(string $id, string $type) : Balance
{
$stripeBalance = $this->balanceInstance->retrieve([ 'stripe_account' => $id ]);
$balance = new Balance();
$balance->setAmount($stripeBalance->$type[0]->amount)
->setCurrency($stripeBalance->$type[0]->currency);
return $balance;
}
/**
* Delete a merchant accont
* @param Account $account
......
<?php
namespace Minds\Core\Payments\Stripe\Instances;
use Minds\Common\StaticToInstance;
use Minds\Core\Config\Config;
use Minds\Core\Di\Di;
/**
* @method BalanceInstance create()
* @method BalanceInstance retrieve()
*/
class BalanceInstance extends StaticToInstance
{
public function __construct(Config $config = null)
{
$config = $config ?? Di::_()->get('Config');
\Stripe\Stripe::setApiKey($config->get('payments')['stripe']['api_key']);
$this->setClass(new \Stripe\Balance);
}
}
<?php
namespace Minds\Core\Payments\Stripe\Instances;
use Minds\Common\StaticToInstance;
use Minds\Core\Config\Config;
use Minds\Core\Di\Di;
/**
* @method ChargeInstance retrieve()
*/
class ChargeInstance extends StaticToInstance
{
public function __construct(Config $config = null)
{
$config = $config ?? Di::_()->get('Config');
\Stripe\Stripe::setApiKey($config->get('payments')['stripe']['api_key']);
$this->setClass(new \Stripe\Charge);
}
}
<?php
namespace Minds\Core\Payments\Stripe\Instances;
use Minds\Common\StaticToInstance;
use Minds\Core\Config\Config;
use Minds\Core\Di\Di;
/**
* @method FileInstance create()
*/
class FileInstance extends StaticToInstance
{
public function __construct(Config $config = null)
{
$config = $config ?? Di::_()->get('Config');
\Stripe\Stripe::setApiKey($config->get('payments')['stripe']['api_key']);
$this->setClass(new \Stripe\File);
}
}
<?php
namespace Minds\Core\Payments\Stripe\Instances;
use Minds\Common\StaticToInstance;
use Minds\Core\Config\Config;
use Minds\Core\Di\Di;
/**
* @method TransferInstance all()
*/
class TransferInstance extends StaticToInstance
{
public function __construct(Config $config = null)
{
$config = $config ?? Di::_()->get('Config');
\Stripe\Stripe::setApiKey($config->get('payments')['stripe']['api_key']);
$this->setClass(new \Stripe\Transfer);
}
}
......@@ -63,6 +63,9 @@ class Manager
'transfer_data' => [
'destination' => $intent->getStripeAccountId(),
],
'metadata' => [
'user_guid' => $intent->getUserGuid(),
],
];
if ($intent->getServiceFee()) {
......
<?php
namespace Minds\Core\Payments\Stripe\Transactions;
use Minds\Core\Payments\Stripe\Connect\Account;
use Minds\Core\Payments\Stripe\Instances\TransferInstance;
use Minds\Core\Payments\Stripe\Instances\ChargeInstance;
use Minds\Core\Di\Di;
use Minds\Common\Repository\Response;
class Manager
{
/** @var EntitiesBuilder $entitiesBuilder */
private $entitiesBuilder;
/** @var TransferInstance $transferInstance */
private $transferInstance;
/** @var ChargeInstance $chargeInstance */
private $chargeInstance;
public function __construct($entitiesBuilder = null, $transferInstance = null, $chargeInstance = null)
{
$this->entitiesBuilder = $entitiesBuilder ?? Di::_()->get('EntitiesBuilder');
$this->transferInstance = $transferInstance ?? new TransferInstance();
$this->chargeInstance = $chargeInstance ?? new ChargeInstance();
}
/**
* Return transactions from an account object
* @param Account $account
* @return Response[Transaction]
*/
public function getByAccount(Account $account): Response
{
$transfers = $this->transferInstance->all([ 'destination' => $account->getId() ]);
$response = new Response();
foreach ($transfers->autoPagingIterator() as $transfer) {
try {
$payment = $this->chargeInstance->retrieve($transfer->source_transaction);
} catch (\Exception $e) {
continue;
}
$transaction = new Transaction();
$transaction->setId($transfer->id)
->setTimestamp($transfer->created)
->setGross($payment->amount)
->setFees(0)
->setNet($transfer->amount)
->setCurrency($transfer->currency)
->setCustomerUserGuid($payment->metadata['user_guid'])
->setCustomerUser($this->entitiesBuilder->single($payment->metadata['user_guid']));
$response[] = $transaction;
}
return $response;
}
}
<?php
namespace Minds\Core\Payments\Stripe\Transactions;
use Minds\Entities\User;
use Minds\Traits\MagicAttributes;
class Transaction
{
use MagicAttributes;
/** @var string $id */
private $id;
/** @var int $timestamp */
private $timestamp;
/** @var int $gross */
private $gross;
/** @var string $currency */
private $currency;
/** @var int $fees */
private $fees;
/** @var int $net */
private $net;
/** @var string $customerGuid */
private $customerUserGuid;
/** @var User $customerUser */
private $customerUser;
/**
* Expose to the public apis
* @param array $extend
* @return array
*/
public function export(array $extend = []) : array
{
return [
'id' => $this->id,
'timestamp' => $this->timestamp,
'gross' => $this->gross,
'currency' => $this->currency,
'fees' => $this->fees,
'net' => $this->net,
'customer_user_guid' => $this->userGuid,
'customer_user' => $this->customerUser ? $this->customerUser->export() : null,
];
}
}
......@@ -1445,3 +1445,5 @@ CREATE TABLE minds.email_campaign_logs (
email_campaign_id text,
PRIMARY KEY (receiver_guid, time_sent)
) WITH CLUSTERING ORDER BY (time_sent desc);
ALTER TABLE minds.views ADD owner_guid text;
\ No newline at end of file
<?php
namespace Minds\Core\Security;
use Minds\Core\Config;
use Minds\Core\Di\Di;
use Minds\Core\Session;
use Lcobucci\JWT;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use Zend\Diactoros\Uri;
class SignedUri
{
/** @Var JWT\Builder $jwtBuilder */
private $jwtBuilder;
/** @var JWT\Parser $jwtParser */
private $jwtParser;
/** @var Config $config */
private $config;
public function __construct($jwtBuilder = null, $jwtParser = null, $config = null)
{
$this->jwtBuilder = $jwtBuilder ?? new JWT\Builder;
$this->jwtParser = $jwtParser ?? new JWT\Parser();
$this->config = $config ?? Di::_()->get('Config');
}
/**
* Sign the uri
* @param string $uri
* @param int $ttl - defaults to 1 day
* @return string
*/
public function sign($uri, $expires = 86400): string
{
$uri = new Uri($uri);
$expires = (new \DateTime())->modify('midnight first day of next month')->modify('+1 month')->getTimestamp();
$token = (new $this->jwtBuilder)
//->setId((string) $uri)
->setExpiration($expires)
->set('uri', (string) $uri)
->set('user_guid', (string) Session::getLoggedInUser()->getGuid())
->sign(new Sha256, $this->config->get('sessions')['private_key'])
->getToken();
$signedUri = $uri->withQuery("jwtsig=$token");
return (string) $signedUri;
}
/**
* Confirm signed uri
* @param string $uri
* @return string
*/
public function confirm($uri): bool
{
$providedUri = new Uri($uri);
parse_str($providedUri->getQuery(), $queryParams);
$providedSig = $queryParams['jwtsig'];
$token = $this->jwtParser->parse($providedSig);
if (!$token->verify(new Sha256, $this->config->get('sessions')['private_key'])) {
return false;
}
return ((string) $token->getClaim('uri') === (string) $providedUri->withQuery(''));
}
}
......@@ -4,15 +4,22 @@
*/
namespace Minds\Core\Sockets;
use Minds\Core\Data\PubSub;
use Minds\Core\Di\Di;
use Minds\Core\Config;
use Minds\Entities\User;
class Events
{
/**
* @var PubSub\Redis\Client
*/
private $redis;
/**
* @var MsgPack
*/
private $msgpack;
private $prefix = 'socket.io';
private $prefix = 'socket.io#';
private $rooms = [];
private $flags = [];
......@@ -25,7 +32,6 @@ class Events
{
$this->redis = $redis ?: Di::_()->get('PubSub\Redis');
$this->msgpack = $msgpack ?: new MsgPack();
$this->prefix = (isset($config['socket-prefix']) ? $config['socket-prefix'] : 'socket.io') . '#';
}
public function emit(/*$event, ...$data*/)
......@@ -82,7 +88,7 @@ class Events
$packed = str_replace(pack('c', 0xdb), pack('c', 0xd9), $packed);
}
// Publish
// Publish - TODO: Log + track possible Redis failures if false is returned
$this->redis->publish($this->prefix . $packet['nsp'] . '#', $packed);
// Reset
......
......@@ -67,7 +67,7 @@ class S3 implements ServiceInterface
$mimeType = $finfo->buffer($data);
$write = $this->s3->putObject([
'ACL' => 'public-read',
// 'ACL' => 'public-read',
'Bucket' => Config::_()->aws['bucket'],
'Key' => $this->filepath,
'ContentType' => $mimeType,
......@@ -121,6 +121,20 @@ class S3 implements ServiceInterface
}
}
/**
* Return a signed url
* @return string
*/
public function getSignedUrl(): string
{
$cmd = $this->s3->getCommand('GetObject', [
'Bucket' => Config::_()->aws['bucket'],
'Key' => $this->filepath,
]);
$request = $this->s3->createPresignedRequest($cmd, '+20 minutes');
return (string) $request->getUri();
}
public function seek($offset = 0)
{
//not supported
......
......@@ -266,6 +266,9 @@ class Manager
throw new \Exception("Not implemented ETH yet");
break;
case 'usd':
if (!$this->receiver->getMerchant() || !$this->receiver->getMerchant()['id']) {
throw new \Exception("This channel is not able to receive USD at the moment");
}
$intent = new PaymentIntent();
$intent
->setUserGuid($this->sender->getGuid())
......
......@@ -3,6 +3,7 @@ namespace Minds\Entities;
use Minds\Helpers;
use Minds\Core;
use Minds\Core\Di\Di;
use Minds\Core\Queue;
use Minds\Core\Analytics;
......@@ -282,6 +283,8 @@ class Activity extends Entity
$export['hide_impressions'] = $this->hide_impressions;
}
$export['thumbnails'] = $this->getThumbnails();
switch ($this->custom_type) {
case 'video':
if ($this->custom_data['guid']) {
......@@ -292,7 +295,11 @@ class Activity extends Entity
// fix old images src
if (is_array($export['custom_data']) && strpos($export['custom_data'][0]['src'], '/wall/attachment') !== false) {
$export['custom_data'][0]['src'] = Core\Config::_()->cdn_url . 'fs/v1/thumbnail/' . $this->entity_guid;
$this->custom_data[0]['src'] = $export['custom_data'][0]['src'];
}
// go directly to cdn
$mediaManager = Di::_()->get('Media\Image\Manager');
$export['custom_data'][0]['src'] = $export['thumbnails']['xlarge'];
break;
}
......@@ -723,6 +730,27 @@ class Activity extends Entity
return $this->ownerObj;
}
/**
* Return thumbnails array to be used with export
* @return array
*/
public function getThumbnails(): array
{
$thumbnails = [];
switch ($this->custom_type) {
case 'video':
break;
case 'batch':
$mediaManager = Di::_()->get('Media\Image\Manager');
$sizes = [ 'xlarge', 'large' ];
foreach ($sizes as $size) {
$thumbnails[$size] = $mediaManager->getPublicAssetUri($this, $size);
}
break;
}
return $thumbnails;
}
/**
* Return a preferred urn
* @return string
......
......@@ -5,6 +5,7 @@
namespace Minds\Entities;
use Minds\Core;
use Minds\Core\Di\Di;
use Minds\Helpers;
class Image extends File
......@@ -34,17 +35,18 @@ class Image extends File
$size = '';
}
if (isset($CONFIG->cdn_url) && !$this->getFlag('paywall') && !$this->getWireThreshold()) {
$base_url = $CONFIG->cdn_url;
} else {
$base_url = \elgg_get_site_url();
}
// if (isset($CONFIG->cdn_url) && !$this->getFlag('paywall') && !$this->getWireThreshold()) {
// $base_url = $CONFIG->cdn_url;
// } else {
// $base_url = \elgg_get_site_url();
// }
if ($this->access_id != 2) {
$base_url = \elgg_get_site_url();
}
// if ($this->access_id != 2) {
// $base_url = \elgg_get_site_url();
// }
$mediaManager = Di::_()->get('Media\Image\Manager');
return $base_url. 'api/v1/media/thumbnails/' . $this->guid . '/'.$size;
return $mediaManager->getPublicAssetUri($this, $size);
}
protected function getIndexKeys($ia = false)
......@@ -213,7 +215,8 @@ class Image extends File
public function export()
{
$export = parent::export();
$export['thumbnail_src'] = $this->getIconUrl();
$export['thumbnail_src'] = $this->getIconUrl('xlarge');
$export['thumbnail'] = $export['thumbnail_src'];
$export['thumbs:up:count'] = Helpers\Counters::get($this->guid, 'thumbs:up');
$export['thumbs:down:count'] = Helpers\Counters::get($this->guid, 'thumbs:down');
$export['description'] = $this->description; //videos need to be able to export html.. sanitize soon!
......
......@@ -8,6 +8,7 @@ namespace Minds\Entities;
use Minds\Core;
use Minds\Core\Media\Services\Factory as ServiceFactory;
use Minds\Core\Di\Di;
use cinemr;
use Minds\Helpers;
......@@ -39,8 +40,8 @@ class Video extends Object
*/
public function getSourceUrl($transcode = '720.mp4')
{
$url = Core\Config::_()->cinemr_url . $this->cinemr_guid . '/' . $transcode;
return $url;
$mediaManager = Di::_()->get('Media\Video\Manager');
return $mediaManager->getPublicAssetUri($this, $transcode);
}
/**
......@@ -62,13 +63,16 @@ class Video extends Object
public function getIconUrl($size = "medium")
{
$domain = elgg_get_site_url();
global $CONFIG;
if (isset($CONFIG->cdn_url) && !$this->getFlag('paywall') && !$this->getWireThreshold()) {
$domain = $CONFIG->cdn_url;
}
// $domain = elgg_get_site_url();
// global $CONFIG;
// if (isset($CONFIG->cdn_url) && !$this->getFlag('paywall') && !$this->getWireThreshold()) {
// $domain = $CONFIG->cdn_url;
// }
// return $domain . 'api/v1/media/thumbnails/' . $this->guid . '/' . $this->time_updated;
return $domain . 'api/v1/media/thumbnails/' . $this->guid . '/' . $this->time_updated;
$mediaManager = Di::_()->get('Media\Image\Manager');
return $mediaManager->getPublicAssetUri($this, 'medium');
}
public function getURL()
......
......@@ -61,6 +61,10 @@ class RepositorySpec extends ObjectBehavior
->shouldBeCalled()
->willReturn('urn:test:123123');
$view->getOwnerGuid()
->shouldBeCalled()
->wilLReturn('789');
$view->getPageToken()
->shouldBeCalled()
->willReturn('1234-qwe-qwe-1234');
......@@ -98,13 +102,14 @@ class RepositorySpec extends ObjectBehavior
$statement['values'][2]->toInt() === 29 &&
$statement['values'][3]->uuid() === 'abc-123-456-def' &&
$statement['values'][4] === 'urn:test:123123' &&
$statement['values'][5] === '1234-qwe-qwe-1234' &&
$statement['values'][6] === 5 &&
$statement['values'][7] === 'php' &&
$statement['values'][8] === 'phpspec' &&
$statement['values'][9] === 'test' &&
$statement['values'][10] === 'urn:phpspec:234234' &&
$statement['values'][11] === 100;
$statement['values'][5] === '789' &&
$statement['values'][6] === '1234-qwe-qwe-1234' &&
$statement['values'][7] === 5 &&
$statement['values'][8] === 'php' &&
$statement['values'][9] === 'phpspec' &&
$statement['values'][10] === 'test' &&
$statement['values'][11] === 'urn:phpspec:234234' &&
$statement['values'][12] === 100;
}), true)
->shouldBeCalled()
->willReturn(true);
......@@ -143,6 +148,10 @@ class RepositorySpec extends ObjectBehavior
->shouldBeCalled()
->willReturn('urn:test:123123');
$view->getOwnerGuid()
->shouldBeCalled()
->willReturn(789);
$view->getPageToken()
->shouldBeCalled()
->willReturn('1234-qwe-qwe-1234');
......@@ -180,13 +189,14 @@ class RepositorySpec extends ObjectBehavior
$statement['values'][2]->toInt() === 29 &&
$statement['values'][3]->time() === $now * 1000 &&
$statement['values'][4] === 'urn:test:123123' &&
$statement['values'][5] === '1234-qwe-qwe-1234' &&
$statement['values'][6] === 5 &&
$statement['values'][7] === 'php' &&
$statement['values'][8] === 'phpspec' &&
$statement['values'][9] === 'test' &&
$statement['values'][10] === 'urn:phpspec:234234' &&
$statement['values'][11] === 100;
$statement['values'][5] === '789' &&
$statement['values'][6] === '1234-qwe-qwe-1234' &&
$statement['values'][7] === 5 &&
$statement['values'][8] === 'php' &&
$statement['values'][9] === 'phpspec' &&
$statement['values'][10] === 'test' &&
$statement['values'][11] === 'urn:phpspec:234234' &&
$statement['values'][12] === 100;
}), true)
->shouldBeCalled()
->willReturn(true);
......
<?php
namespace Spec\Minds\Core\Media\Image;
use Minds\Core\Media\Image\Manager;
use Minds\Core\Config;
use Minds\Core\Security\SignedUri;
use Minds\Entities\Activity;
use Minds\Entities\Image;
use Minds\Entities\Video;
use Minds\Core\Comments\Comment;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ManagerSpec extends ObjectBehavior
{
private $config;
private $signedUri;
public function let(Config $config, SignedUri $signedUri)
{
$this->beConstructedWith($config, $signedUri);
$this->config = $config;
$this->signedUri = $signedUri;
}
public function it_is_initializable()
{
$this->shouldHaveType(Manager::class);
}
public function it_should_return_public_asset_uri()
{
$activity = new Activity();
$activity->set('entity_guid', 123);
$this->config->get('cdn_url')
->willReturn('https://minds.dev/');
$uri = 'https://minds.dev/fs/v1/thumbnail/123/xlarge';
$this->signedUri->sign($uri, Argument::any())
->willReturn('signed url will be here');
$this->getPublicAssetUri($activity)
->shouldBe('signed url will be here');
}
public function it_should_return_public_asset_uri_for_image()
{
$entity = new Image();
$entity->set('guid', 123);
$this->config->get('cdn_url')
->willReturn('https://minds.dev/');
$uri = 'https://minds.dev/fs/v1/thumbnail/123/xlarge';
$this->signedUri->sign($uri, Argument::any())
->willReturn('signed url will be here');
$this->getPublicAssetUri($entity)
->shouldBe('signed url will be here');
}
public function it_should_return_public_asset_uri_for_video()
{
$entity = new Video();
$entity->set('guid', 123);
$this->config->get('cdn_url')
->willReturn('https://minds.dev/');
$uri = 'https://minds.dev/fs/v1/thumbnail/123/xlarge';
$this->signedUri->sign($uri, Argument::any())
->willReturn('signed url will be here');
$this->getPublicAssetUri($entity)
->shouldBe('signed url will be here');
}
public function it_should_return_public_asset_uri_for_comment()
{
$entity = new Comment();
$entity->setAttachment('attachment_guid', '123');
$this->config->get('cdn_url')
->willReturn('https://minds.dev/');
$uri = 'https://minds.dev/fs/v1/thumbnail/123/xlarge';
$this->signedUri->sign($uri, Argument::any())
->willReturn('signed url will be here');
$this->getPublicAssetUri($entity)
->shouldBe('signed url will be here');
}
}
<?php
namespace Spec\Minds\Core\Media\Video;
use Minds\Core\Config;
use Aws\S3\S3Client;
use Minds\Core\Media\Video\Manager;
use Minds\Entities\Video;
use Psr\Http\Message\RequestInterface;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ManagerSpec extends ObjectBehavior
{
private $config;
private $s3;
public function let(Config $config, S3Client $s3)
{
$this->beConstructedWith($config, $s3);
$this->config = $config;
$this->s3 = $s3;
}
public function it_is_initializable()
{
$this->shouldHaveType(Manager::class);
}
public function it_should_get_a_720p_video(RequestInterface $request, \Aws\CommandInterface $cmd)
{
$this->config->get('transcoder')
->willReturn([
'dir' => 'dir',
]);
$this->config->get('aws')
->willReturn([
'region' => 'us-east-1',
'useRoles' => true,
]);
$this->s3->getCommand('GetObject', [
'Bucket' => 'cinemr',
'Key' => 'dir/123/720.mp4'
])
->shouldBeCalled()
->willReturn($cmd);
$request->getUri()
->willReturn('s3-signed-url-here');
$this->s3->createPresignedRequest(Argument::any(), Argument::any())
->willReturn($request);
$video = new Video();
$video->set('cinemr_guid', 123);
$this->getPublicAssetUri($video, '720.mp4')
->shouldBe('s3-signed-url-here');
}
}
......@@ -7,6 +7,8 @@ use Minds\Core\Payments\Stripe\Connect\Account;
use Minds\Core\Entities\Actions\Save;
use Minds\Core\Payments\Stripe\Connect\Delegates\NotificationDelegate;
use Minds\Core\Payments\Stripe\Instances\AccountInstance;
use Minds\Core\Payments\Stripe\Instances\BalanceInstance;
use Minds\Core\Payments\Stripe\Instances\FileInstance;
use Minds\Entities\User;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
......@@ -16,13 +18,17 @@ class ManagerSpec extends ObjectBehavior
private $save;
private $notificationDelegate;
private $accountInstance;
private $balanceInstance;
private $fileInstance;
public function let(Save $save, NotificationDelegate $notificationDelegate, AccountInstance $accountInstance)
public function let(Save $save, NotificationDelegate $notificationDelegate, AccountInstance $accountInstance, BalanceInstance $balanceInstance, FileInstance $fileInstance)
{
$this->beConstructedWith($save, $notificationDelegate, $accountInstance);
$this->beConstructedWith($save, $notificationDelegate, $accountInstance, $balanceInstance, $fileInstance);
$this->save = $save;
$this->notificationDelegate = $notificationDelegate;
$this->accountInstance = $accountInstance;
$this->balanceInstance = $balanceInstance;
$this->fileInstance = $fileInstance;
}
public function it_is_initializable()
......@@ -126,6 +132,31 @@ class ManagerSpec extends ObjectBehavior
'verification' => (object) [
'disabled_reason' => null,
],
'settings' => (object) [
'payouts' => (object) [
'schedule' => (object) [
'interval' => 1,
'delay_days' => 2,
'monthly_anchor' => 31,
],
],
],
]);
$this->balanceInstance->retrieve([ 'stripe_account' => 'acc_123'])
->willReturn((object) [
'pending' => [
(object) [
'amount' => 100,
'currency' => 'GBP',
],
],
'available' => [
(object) [
'amount' => 100,
'currency' => 'GBP',
],
],
]);
$account = $this->getByAccountId('acc_123');
......@@ -181,6 +212,31 @@ class ManagerSpec extends ObjectBehavior
'verification' => (object) [
'disabled_reason' => null,
],
'settings' => (object) [
'payouts' => (object) [
'schedule' => (object) [
'interval' => 1,
'delay_days' => 2,
'monthly_anchor' => 31,
]
]
]
]);
$this->balanceInstance->retrieve([ 'stripe_account' => 'acc_123'])
->willReturn((object) [
'pending' => [
(object) [
'amount' => 100,
'currency' => 'GBP',
],
],
'available' => [
(object) [
'amount' => 100,
'currency' => 'GBP',
],
],
]);
$user = new User();
......
<?php
namespace Spec\Minds\Core\Security;
use Minds\Core\Security\SignedUri;
use Minds\Entities\User;
use Minds\Core\Config;
use Lcobucci\JWT;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class SignedUriSpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType(SignedUri::class);
}
public function it_sign_a_uri(Config $config)
{
$user = new User();
$user->set('guid', 123);
$user->set('username', 'phpspec');
\Minds\Core\Session::setUser($user);
$this->beConstructedWith(null, null, $config);
$config->get('sessions')
->willReturn([
'private_key' => 'priv-key'
]);
$this->sign("https://minds-dev/foo")
->shouldContain("https://minds-dev/foo?jwtsig=");
}
public function it_should_verify_a_uri_was_signed(Config $config)
{
$this->beConstructedWith(null, null, $config);
$config->get('sessions')
->willReturn([
'private_key' => 'priv-key'
]);
$uri = "https://minds-dev/foo?jwtsig=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NzI1NjY0MDAsInVyaSI6Imh0dHBzOlwvXC9taW5kcy1kZXZcL2ZvbyIsInVzZXJfZ3VpZCI6IjEyMyJ9.jqOq0k-E4h1I0PHnc_WkmWqXonRU4yWq_ymoOYoaDvc";
$this->confirm($uri)
->shouldBe(true);
}
public function it_should_not_very_a_wrongly_signed_uri(Config $config)
{
$this->beConstructedWith(null, null, $config);
$config->get('sessions')
->willReturn([
'private_key' => 'priv-key'
]);
$uri = "https://minds-dev/bar?jwtsig=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NzI1NjY0MDAsInVyaSI6Imh0dHBzOlwvXC9taW5kcy1kZXZcL2ZvbyIsInVzZXJfZ3VpZCI6IjEyMyJ9.jqOq0k-E4h1I0PHnc_WkmWqXonRU4yWq_ymoOYoaDvc";
$this->confirm($uri)
->shouldBe(false);
}
}
......@@ -3,6 +3,7 @@
"description": "The core minds social engine",
"require": {
"php": "~7.1",
"ext-redis": "~4.3",
"aws/aws-sdk-php": "^3.38",
"braintree/braintree_php": "3.5.0",
"datastax/php-driver": "1.2.2",
......