...
 
Commits (9)
......@@ -2,13 +2,22 @@
/**
* Converts a static class to use instances
*/
namespace Minds\Common;
use ReflectionClass;
use ReflectionException;
class StaticToInstance
{
/** @var $class */
/** @var ReflectionClass */
private $class;
/**
* StaticToInstance constructor.
* @param $class
* @throws ReflectionException
*/
public function __construct($class)
{
$this->setClass($class);
......@@ -16,11 +25,13 @@ class StaticToInstance
/**
* Set the class in question
* @return StripeStaticToOO
* @param $class
* @return static
* @throws ReflectionException
*/
public function setClass($class)
{
$this->class = new \ReflectionClass($class);
$this->class = new ReflectionClass($class);
return clone $this;
}
......@@ -28,7 +39,7 @@ class StaticToInstance
* Call the static functions as OO style
* @param string $method
* @param array $arguments
* @return midex
* @return mixed
*/
public function __call($method, $arguments)
{
......
......@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
<style>
p {
p, li {
font-family: Roboto,Arial,sans-serif;
font-size: 18px;
line-height: 1.5;
......
......@@ -45,49 +45,78 @@ class All extends Cli\Controller implements Interfaces\CliControllerInterface
/**
* @throws CliException
*/
public function sync_activity()
public function sync_activity(): void
{
return $this->syncBy('activity', null, $this->getOpt('metric'), $this->getOpt('from'), $this->getOpt('to'));
list($from, $to) = $this->getTimeRangeFromArgs();
$this->syncBy('activity', null, $this->getOpt('metric'), $from, $to);
}
/**
* @throws CliException
*/
public function sync_images()
public function sync_images(): void
{
return $this->syncBy('object', 'image', $this->getOpt('metric'), $this->getOpt('from'), $this->getOpt('to'));
list($from, $to) = $this->getTimeRangeFromArgs();
$this->syncBy('object', 'image', $this->getOpt('metric'), $from, $to);
}
/**
* @throws CliException
*/
public function sync_videos()
public function sync_videos(): void
{
return $this->syncBy('object', 'video', $this->getOpt('metric'), $this->getOpt('from'), $this->getOpt('to'));
list($from, $to) = $this->getTimeRangeFromArgs();
$this->syncBy('object', 'video', $this->getOpt('metric'), $from, $to);
}
/**
* @throws CliException
*/
public function sync_blogs()
public function sync_blogs(): void
{
return $this->syncBy('object', 'blog', $this->getOpt('metric'), $this->getOpt('from'), $this->getOpt('to'));
list($from, $to) = $this->getTimeRangeFromArgs();
$this->syncBy('object', 'blog', $this->getOpt('metric'), $from, $to);
}
/**
* @throws CliException
*/
public function sync_groups()
public function sync_groups(): void
{
return $this->syncBy('group', null, $this->getOpt('metric'), $this->getOpt('from'), $this->getOpt('to'));
list($from, $to) = $this->getTimeRangeFromArgs();
$this->syncBy('group', null, $this->getOpt('metric'), $from, $to);
}
/**
* @throws CliException
*/
public function sync_channels()
public function sync_channels(): void
{
return $this->syncBy('user', null, $this->getOpt('metric'), $this->getOpt('from'), $this->getOpt('to'));
list($from, $to) = $this->getTimeRangeFromArgs();
$this->syncBy('user', null, $this->getOpt('metric'), $from, $to);
}
/**
* @return int[]
* @throws CliException
*/
protected function getTimeRangeFromArgs(): array
{
$to = $this->getOpt('to') ?: time();
if ($this->getOpt('from') && $this->getOpt('secsAgo')) {
throw new CliException('Cannot specify both `from` and `secsAgo`');
} elseif (!$this->getOpt('from') && !$this->getOpt('secsAgo')) {
throw new CliException('You should specify either `from` or `secsAgo`');
}
if ($this->getOpt('secsAgo')) {
$from = time() - $this->getOpt('secsAgo');
} else {
$from = $this->getOpt('from');
}
return [$from, $to];
}
/**
......@@ -99,26 +128,22 @@ class All extends Cli\Controller implements Interfaces\CliControllerInterface
* @throws CliException
* @throws Exception
*/
protected function syncBy($type, $subtype, $metric, $from, $to)
protected function syncBy($type, $subtype, $metric, $from, $to): void
{
if (!$metric) {
throw new CliException('Missing --metric flag');
throw new CliException('Missing `metric`');
}
if (!$from || !is_numeric($from)) {
throw new CliException('Missing or invalid --from flag');
}
if (!$to) {
$to = time();
throw new CliException('Missing or invalid `from` value');
}
if (!is_numeric($to)) {
throw new CliException('Invalid --to flag');
if (!$to || !is_numeric($to)) {
throw new CliException('Invalid `to` value');
}
if ($from > $to) {
throw new CliException('--from should be before --to');
throw new CliException('`from` must be lesser than `to`');
}
error_reporting(E_ALL);
......@@ -126,7 +151,12 @@ class All extends Cli\Controller implements Interfaces\CliControllerInterface
$displayType = trim(implode(':', [$type, $subtype]), ':');
$this->out("Syncing {$displayType} -> {$metric}");
$this->out(sprintf(
"%s -> %s",
date('r', $from),
date('r', $to),
));
$this->out("Syncing {$displayType} / {$metric}");
$this->sync
->setType($type ?: '')
......
......@@ -43,9 +43,12 @@ class content implements Interfaces\Api
}
$type = '';
$algorithm = strtolower($_GET['algorithm'] ?? 'top');
switch ($pages[1]) {
case 'activities':
$type = 'activity';
$algorithm = 'latest';
break;
case 'images':
$type = 'object:image';
......@@ -127,7 +130,7 @@ class content implements Interfaces\Api
'custom_type' => null,
'limit' => $limit,
'type' => $type,
'algorithm' => 'top',
'algorithm' => $algorithm,
'period' => '7d',
'sync' => $sync,
'from_timestamp' => $fromTimestamp,
......@@ -159,7 +162,7 @@ class content implements Interfaces\Api
try {
$result = $this->getData($entities, $opts, $asActivities, $sync);
if ($result->count() <= static::MIN_COUNT) {
if ($opts['algorithm'] !== 'latest' && $result->count() <= static::MIN_COUNT) {
$opts['algorithm'] = 'latest';
$result = $this->getData($entities, $opts, $asActivities, $sync);
}
......
......@@ -61,6 +61,12 @@ class wire implements Interfaces\Api
$recurring = isset($_POST['recurring']) ? $_POST['recurring'] : false;
$recurringInterval = $_POST['recurring_interval'] ?? 'once';
if ($recurring && $recurringInterval === 'once') {
$recurringInterval = 'monthly';
// Client side bug we need to track down, so lets log in Sentry
\Sentry\captureMessage("Recurring Subscription was created with 'once' interval");
}
if (!$amount) {
return Factory::response(['status' => 'error', 'message' => 'you must send an amount']);
}
......
......@@ -4,18 +4,27 @@
*/
namespace Minds\Core;
use Minds\Common\StaticToInstance;
use Minds\Helpers\Counters as CountersHelper;
use ReflectionException;
class Counters
/**
* Class Counters
* @package Minds\Core
* @method increment($entity, $metric, $value = 1, $client = null)
* @method decrement($entity, $metric, $value = 1, $client = null)
* @method incrementBatch($entities, $metric, $value = 1, $client = null)
* @method get($entity, $metric, $cache = true, $client = null)
* @method clear($entity, $metric, $value = 0, $client = null)
*/
class Counters extends StaticToInstance
{
/**
* @param mixed $entity
* @param string $metric
* @param bool $cache
* @return int
* Counters constructor.
* @throws ReflectionException
*/
public function get($entity, string $metric, $cache = true): int
public function __construct()
{
return CountersHelper::get($entity, $metric, $cache);
parent::__construct(new CountersHelper());
}
}
Our team has been heads down in the lab developing open source technology that is changing the world. As always, our goal is to provide you with a platform that enables the free exchange of ideas, protects your digital rights and fairly compensates you for your contributions to the network.
Introducing Minds Pro (beta), a new revenue model for content creators.
- Get paid for your traffic and referrals
- Launch your own website
- Receive multi-currency tips and subscription payments from fans
- Supports video, images, blogs and more
| |
|:--:|
| [![Upgrade to Pro](https://cdn-assets.minds.com/emails/upgrade-to-pro.png){=150x}](https://www.minds.com/pro?__e_ct_guid=<?= $vars['guid']?>&campaign=<?= $vars['campaign']?>&topic=<?= $vars['topic'] ?>&validator=<?= $vars['validator'] ?>) |
| |
Thank you for your support!
This diff is collapsed.
<?php
namespace Minds\Core\Security;
/**
* Domains listed here has been blacklisted due to spam.
* Short urls are also not allowed due to security issues.
*/
class ProhibitedDomains
{
/** @var array */
const DOMAINS = [
'movieblog.tumblr.com',
'moviehdstream.wordpress.com',
'moviehq.tumblr.com',
'moviehq.webs.com',
'moviehq.wordpress.com',
'movieo.wordpress.com',
'movieonline.tumblr.com',
'movieonline.webs.com',
'movieonline.wordpress.com',
'movieonlinehd.tumblr.com',
'movieonlinehd.webs.com',
'movieonlinehd.wordpress.com',
'movies.tumblr.com',
'moviesf.tumblr.com',
'moviesgodetia.com',
'movieslinks4u',
'moviesmount.com',
'moviesmonster.biz',
'moviesondesktop',
'moviesonlinefree.biz',
'moviestream.wordpress.com',
'movieontop.com',
'afllivestreaming.com.au',
'londonolympiccorner',
'nrllivestreaming.com.au',
'24x7livestreamtvchannels.com',
'www.edogo.us',
'all4health.in',
'watches4a.co.uk',
'es.jennyjoseph.com',
'allsportslive24x7.blogspot.com',
'boxing-tv-2014-live-stream.blogspot.com',
'amarblogdalima.blogspot.com',
'www.officialtvstream.com.es',
'topsalor.com',
'busybo.org',
'www.nowvideo.sx',
'180upload.com',
'allmyvideos.net',
'busybo.org',
'hdmovieshouse.biz',
'sportblog.info',
'psport.space',
'discus.space',
'euro2016.it.ua',
'neymar.space',
'espnstream.space',
'2016.vn.u',
'blogstream.space',
'liveextratime.xyz',
'thebestlive.xyz',
'streamoffside.xyz',
'sportmaster2014.page.tl',
'bloggersdelight.dk',
'watchsportslive.space',
'freeforward.xyz',
'live4sports.xyz',
'streamfun.xyz',
'angelfire.com',
'streamtime.xyz',
'futebol2star.com',
'live2sport.com',
'newssports.space',
'onlineolympics.xyz',
'liveolympics.xyz',
'streamontv.xyz',
'londonschedule.com',
'onlineolympics.space',
'sportwinning.xyz',
'streamworld.xyz',
'streamtop.xyz',
'livechampion.xyz',
'playstreams.xyz',
'live4sport.xyz',
'streampage.xyz',
'calendarsport.space',
'fsport.space',
'euro2016.od.ua',
'streambig.xyz',
'sportprediction.xyz',
'streamwork.xyz',
'r041.donnael.com',
'2016.lt.ua',
'vipleague.se',
'liveonline.company',
'liveolympics.space',
'seoandvideomarketing.com.au',
'vipbox.sx',
'germanypolandlivestream.club',
'sportgoal.xyz',
'ggdbsale.com',
'gorillasteroids.eu',
'watchlivesports.space',
'penaltyshootout.xyz',
'streamgroup.xyz',
'streamnew.xyz',
'cottonsport.space',
'gosport.space',
'streambest.xyz',
'penaltyspot.xyz',
'streamthe.xyz',
'liveevents.name',
'londonblog.work',
'testcollections.com',
'alfagy.com',
'teravide1974.full-design.com',
'selfnarhasbllaq1980-blog.logdown.com',
'neipononchoi1984.suomiblog.com',
'gemttranlonthe1985.blogzet.com',
'pitchero.com',
'blogolize.com',
'lisbopholsven1974.thezenweb.com',
'blogocial.com',
'tinyblogging.com',
'share.pho.to',
'community.vietfun.com',
'ockuderla1985.full-design.com',
'unmosimla1978.total-blog.com',
'gemttranlonthe1985.blogzet.com',
'rapptubizboe1978.blogminds.com',
'descduclighgon1973.full-design.com',
'ricphosati1972.full-design.com',
'fuddbluslanmaa1975.blogdigy.com',
'smarforcute1976.blogdigy.com',
'xn--90aizihgi.xn--p1ai',
'tinyurl.com',
'bit.ly',
'bit.do',
'123football.space',
'bitly.com',
'j.mp',
'livestreaming.one',
'livestreaming.life',
'forbest.pw',
'olizev.tdska2ll.ru',
'tdska2ll.ru',
'tdska1ll.ru',
'tdska3ll.ru',
'tdska4ll.ru',
'ihmail.ru',
'tdska5ll.ru',
'tdska6ll.ru',
'll.ru',
'shorl.com',
'scorestream.space',
'bestsplayer.xyz',
'worldwideevents.space',
'worldseries.space',
'best247chemist.net',
'9tn.ru',
'futbolkin2013.ru',
'playnowstore.com',
'qr-url.tk',
'watchonlinerugby.net',
'esecuritys.com',
'rufile.no-ip.ca',
'imzonline.com',
'femeedia.com',
'mediomatic.com',
'savemoneyeasily.com',
'option1pro.com',
'perron07.nl',
'movieonrails.com',
'topmoviestoday.com',
'playnowstore.com',
'g-files.biz',
'dawnloadonline.com',
'thedirsite.com',
'siteslocate.com',
'mydrugdir.com',
'find24hs.com',
'veeble.org',
'movieonrails.com',
'bestmoviehd.net',
'putmovies.info',
'awarefinance.com',
'shurll.com',
'acceptsearch.com',
'signforcover.com',
'raisengine.com',
'rocketcarrental.com',
'godsearchs.com',
'listenhanced.com',
'find24hs.com',
'findinform.com',
'sitesworlds.com',
'rocketcarrental.com',
'thedirsite.com',
'getboook.com',
'pokerarena88.com',
'aquamelia.com',
'beautyskintalks.com',
'getmooovie.com',
'getdriversss.com',
'getsoooft.com',
'getgamesss.com',
'abrts.pro',
'leadbit.biz',
'efght.pro',
'qyresearcheurope.com',
'plusfreemaxfr.com',
'getappmac.com',
'getharlemhealthy.org',
'goo.gl',
'getmooovie.com',
'marketreportscenter.com',
'getsooft.com',
'myowndom.ru',
'print-mgn.ru',
'wiki-data.ru',
'velobog.ru',
'mobisony.ru',
'dzeroki.ru',
'slimkor.ru',
'kak-brosit-kyrit.ru',
'jinyurl.com',
'urlin.us',
'capillus.com',
'siteprofissional.com',
'mitersawjudge.com',
'mohajreen-jeeda.com',
'jobberies.com',
'bestfilms.site',
'baystudios.ch',
'elvenarhack.bid',
'essencephskincare.com',
'blog2learn.com',
'superrugbyonline.net',
'superrugby18.livejournal.com',
'expertairco.com',
'draesthetica.co.uk',
'sphere.social',
'saveabookmarks.xyz',
'/t.co',
'samuelsconstruction.build',
'pmwares.com',
'watchesofwales.co.uk',
'zotero.org',
'speakerdeck.com',
'freesiteslike.com',
'pusha.se',
'vrootdownload.org',
'rubberwebshop.nl',
'restaurerlecorps.info',
'discretthemes.info',
'bride-forever.com',
'simplesmetamorphoses.info',
'mp3gain.com',
'mp4gain.com',
'ttlink.com',
'onepost.cf',
'getmefunds.com',
'vikinail.pl',
'typesofbeauty.info',
'joie6portia93.bloglove.cc',
'htgtea.com',
'tblogz.com',
'liveinternet.ru',
'.diowebhost.com',
'/yoursite.com',
'reworkedgames.eu',
'mp3gain.sourceforge.net',
'pages10.com',
'nudegirIs.info',
'aidagirls.com',
'alsoloves.com',
'hotswishes.com',
'instaphoto.club',
'intimspace.com',
'pornopoisk.info',
'localmodels.online',
'kaikki-mallit.com',
'hotswishes.com',
];
}
This diff is collapsed.
......@@ -90,4 +90,26 @@ class Text
{
return (string) $value;
}
/**
* Runs through a body of text, checking it for values.
*
* @param [type] $haystack - Body of text.
* @param [type] $needles - Array of values to be searched for.
* @param integer $offset - offset to start.
* @return boolean|string - The matching value.
*/
public static function strposa($haystack, $needles, $offset = 0)
{
if (!is_array($needles)) {
$needles = [$needles];
}
foreach ($needles as $query) {
if (stripos($haystack, $query, $offset) !== false) {
// stop on first true result
return $query;
}
}
return false;
}
}
......@@ -275,28 +275,26 @@ class ManagerSpec extends ObjectBehavior
->shouldReturn(true);
}
public function it_should_abort_if_spam(Blog $blog)
public function it_should_check_for_spam(Blog $blog, Spam $spam)
{
$this->beConstructedWith(
$this->repository,
$this->paywallReview,
$this->slug,
$this->feeds,
null,
$this->spam,
$this->search
);
$spamUrl = 'movieblog.tumblr.com';
$blog->getType()
->willReturn('object');
->willReturn('object');
$blog->getSubtype()
->willReturn('blog');
$blog->getBody()
->shouldBeCalled()
->willReturn('movieblog.tumblr.com');
->willReturn('blog');
$this->shouldThrow(new \Exception('Sorry, you included a reference to a domain name linked to spam. You can not use short urls (eg. bit.ly). Please remove it and try again'))
->duringAdd($blog);
$this->spam->check(Argument::any())->shouldBeCalled()->willReturn(true);
$this->add($blog);
}
}
<?php
namespace Spec\Minds\Core\Security;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Minds\Core\Blogs\Blog;
use Minds\Core\Config;
use Minds\Core\Comments\Comment;
use Minds\Entities\User;
use Minds\Entities\Group;
use Minds\Entities\Entity;
use Minds\Core\Security\ProhibitedDomains;
class SpamSpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType('Minds\Core\Security\Spam');
}
public function it_should_detect_spam_in_a_blog(
Blog $blog,
ProhibitedDomains $prohibitedDomains
) {
$blog->getBody()->shouldBeCalled()->willReturn('test bit.ly test');
$blog->getType()->shouldBeCalled()->willReturn('object');
$blog->getSubtype()->shouldBeCalled()->willReturn('blog');
$this->shouldThrow(new \Exception("Sorry, you included a reference to a domain name linked to spam (bit.ly)"))
->duringCheck($blog);
}
public function it_should_detect_spam_in_a_comment(
Comment $comment,
ProhibitedDomains $prohibitedDomains
) {
$comment = new Comment();
$comment->setBody('test bit.ly test');
$comment->setType('comment');
$this->shouldThrow(new \Exception("Sorry, you included a reference to a domain name linked to spam (bit.ly)"))
->duringCheck($comment);
}
public function it_should_detect_spam_in_a_user(
User $user,
ProhibitedDomains $prohibitedDomains
) {
$user = new User('123');
$user['briefdescription'] = 'test bit.ly test';
$user['type'] = 'user';
$this->shouldThrow(new \Exception("Sorry, you included a reference to a domain name linked to spam (bit.ly)"))
->duringCheck($user);
}
public function it_should_detect_spam_in_a_group(
Group $group,
ProhibitedDomains $prohibitedDomains
) {
$group = new Group();
$group->setBriefdescription('test bit.ly test');
$group->setType('group');
$this->shouldThrow(new \Exception("Sorry, you included a reference to a domain name linked to spam (bit.ly)"))
->duringCheck($group);
}
public function it_should_detect_NO_spam_in_a_blog(
Blog $blog,
ProhibitedDomains $prohibitedDomains
) {
$blog->getBody()->shouldBeCalled()->willReturn('test bit.nospam test');
$blog->getType()->shouldBeCalled()->willReturn('object');
$blog->getSubtype()->shouldBeCalled()->willReturn('blog');
$this->check($blog)->shouldReturn(false);
}
public function it_should_detect_NO_spam_in_a_comment(
Comment $comment,
ProhibitedDomains $prohibitedDomains
) {
$comment = new Comment();
$comment->setBody('test bit.nospam test');
$comment->setType('comment');
$this->check($comment)->shouldReturn(false);
}
public function it_should_detect_NO_spam_in_a_user(
User $user,
ProhibitedDomains $prohibitedDomains
) {
$user = new User('123');
$user['briefdescription'] = 'test bit.nospam test';
$user['type'] = 'user';
$this->check($user)->shouldReturn(false);
}
public function it_should_detect_NO_spam_in_a_group(
Group $group,
ProhibitedDomains $prohibitedDomains
) {
$group = new Group();
$group->setBriefdescription('test bit.nospam test');
$group->setType('group');
$this->check($group)->shouldReturn(false);
}
}
......@@ -12,6 +12,7 @@ RUN apk add --no-cache --virtual build-deps \
coreutils \
imagemagick \
nodejs \
npm \
ffmpeg \
&& docker-php-ext-install -j$(nproc) bcmath \
&& docker-php-ext-install -j$(nproc) zip \
......