diff --git a/client/build/components/AssetShareButtons/index.js b/client/build/components/AssetShareButtons/index.js
new file mode 100644
index 00000000..8b54ec2b
--- /dev/null
+++ b/client/build/components/AssetShareButtons/index.js
@@ -0,0 +1,38 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _react = _interopRequireDefault(require("react"));
+
+var _SpaceBetween = _interopRequireDefault(require("@components/SpaceBetween"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var AssetShareButtons = function AssetShareButtons(_ref) {
+ var host = _ref.host,
+ name = _ref.name,
+ shortId = _ref.shortId;
+ return _react.default.createElement(_SpaceBetween.default, null, _react.default.createElement("a", {
+ className: "link--primary",
+ target: "_blank",
+ href: "https://twitter.com/intent/tweet?text=".concat(host, "/").concat(shortId, "/").concat(name)
+ }, "twitter"), _react.default.createElement("a", {
+ className: "link--primary",
+ target: "_blank",
+ href: "https://www.facebook.com/sharer/sharer.php?u=".concat(host, "/").concat(shortId, "/").concat(name)
+ }, "facebook"), _react.default.createElement("a", {
+ className: "link--primary",
+ target: "_blank",
+ href: "http://tumblr.com/widgets/share/tool?canonicalUrl=".concat(host, "/").concat(shortId, "/").concat(name)
+ }, "tumblr"), _react.default.createElement("a", {
+ className: "link--primary",
+ target: "_blank",
+ href: "https://www.reddit.com/submit?url=".concat(host, "/").concat(shortId, "/").concat(name, "&title=").concat(name)
+ }, "reddit"));
+};
+
+var _default = AssetShareButtons;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/components/ClickToCopy/index.js b/client/build/components/ClickToCopy/index.js
new file mode 100644
index 00000000..0c0b93e5
--- /dev/null
+++ b/client/build/components/ClickToCopy/index.js
@@ -0,0 +1,82 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _react = _interopRequireDefault(require("react"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } _setPrototypeOf(subClass.prototype, superClass && superClass.prototype); if (superClass) _setPrototypeOf(subClass, superClass); }
+
+function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
+
+function _getPrototypeOf(o) { _getPrototypeOf = Object.getPrototypeOf || function _getPrototypeOf(o) { return o.__proto__; }; return _getPrototypeOf(o); }
+
+function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
+
+var ClickToCopy =
+/*#__PURE__*/
+function (_React$Component) {
+ function ClickToCopy(props) {
+ var _this;
+
+ _classCallCheck(this, ClickToCopy);
+
+ _this = _possibleConstructorReturn(this, _getPrototypeOf(ClickToCopy).call(this, props));
+ _this.copyToClipboard = _this.copyToClipboard.bind(_assertThisInitialized(_assertThisInitialized(_this)));
+ return _this;
+ }
+
+ _createClass(ClickToCopy, [{
+ key: "copyToClipboard",
+ value: function copyToClipboard(event) {
+ var elementToCopy = event.target.id;
+ var element = document.getElementById(elementToCopy);
+ element.select();
+
+ try {
+ document.execCommand('copy');
+ } catch (err) {
+ this.setState({
+ error: 'Oops, unable to copy'
+ });
+ }
+ }
+ }, {
+ key: "render",
+ value: function render() {
+ var _this$props = this.props,
+ id = _this$props.id,
+ value = _this$props.value;
+ return _react.default.createElement("input", {
+ id: id,
+ value: value,
+ onClick: this.copyToClipboard,
+ type: "text",
+ className: "click-to-copy",
+ readOnly: true,
+ spellCheck: "false"
+ });
+ }
+ }]);
+
+ _inherits(ClickToCopy, _React$Component);
+
+ return ClickToCopy;
+}(_react.default.Component);
+
+var _default = ClickToCopy;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/containers/AssetInfo/view.js b/client/build/containers/AssetInfo/view.js
index a405af12..55eefee1 100644
--- a/client/build/containers/AssetInfo/view.js
+++ b/client/build/containers/AssetInfo/view.js
@@ -17,6 +17,10 @@ var _Row = _interopRequireDefault(require("@components/Row"));
var _SpaceBetween = _interopRequireDefault(require("@components/SpaceBetween"));
+var _AssetShareButtons = _interopRequireDefault(require("@components/AssetShareButtons"));
+
+var _ClickToCopy = _interopRequireDefault(require("@components/ClickToCopy"));
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
@@ -33,80 +37,20 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
-function _getPrototypeOf(o) { _getPrototypeOf = Object.getPrototypeOf || function _getPrototypeOf(o) { return o.__proto__; }; return _getPrototypeOf(o); }
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
-var AssetShareButtons = function AssetShareButtons(_ref) {
- var host = _ref.host,
- name = _ref.name,
- shortId = _ref.shortId;
- return _react.default.createElement(_SpaceBetween.default, null, _react.default.createElement("a", {
- className: "link--primary",
- target: "_blank",
- href: "https://twitter.com/intent/tweet?text=".concat(host, "/").concat(shortId, "/").concat(name)
- }, "twitter"), _react.default.createElement("a", {
- className: "link--primary",
- target: "_blank",
- href: "https://www.facebook.com/sharer/sharer.php?u=".concat(host, "/").concat(shortId, "/").concat(name)
- }, "facebook"), _react.default.createElement("a", {
- className: "link--primary",
- target: "_blank",
- href: "http://tumblr.com/widgets/share/tool?canonicalUrl=".concat(host, "/").concat(shortId, "/").concat(name)
- }, "tumblr"), _react.default.createElement("a", {
- className: "link--primary",
- target: "_blank",
- href: "https://www.reddit.com/submit?url=".concat(host, "/").concat(shortId, "/").concat(name, "&title=").concat(name)
- }, "reddit"));
-};
-
-var ClickToCopy = function ClickToCopy(_ref2) {
- var id = _ref2.id,
- value = _ref2.value,
- copyToClipboard = _ref2.copyToClipboard;
- return _react.default.createElement("input", {
- id: id,
- value: value,
- onClick: copyToClipboard,
- type: "text",
- className: "click-to-copy",
- readOnly: true,
- spellCheck: "false"
- });
-};
+function _getPrototypeOf(o) { _getPrototypeOf = Object.getPrototypeOf || function _getPrototypeOf(o) { return o.__proto__; }; return _getPrototypeOf(o); }
var AssetInfo =
/*#__PURE__*/
function (_React$Component) {
- function AssetInfo(props) {
- var _this;
-
+ function AssetInfo() {
_classCallCheck(this, AssetInfo);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(AssetInfo).call(this, props));
- _this.copyToClipboard = _this.copyToClipboard.bind(_assertThisInitialized(_assertThisInitialized(_this)));
- return _this;
+ return _possibleConstructorReturn(this, _getPrototypeOf(AssetInfo).apply(this, arguments));
}
_createClass(AssetInfo, [{
- key: "copyToClipboard",
- value: function copyToClipboard(event) {
- console.log('event:', event);
- console.log('event.target:', event.target);
- console.log('event.target.id:', event.target.id);
- var elementToCopy = event.target.id;
- var element = document.getElementById(elementToCopy);
- element.select();
-
- try {
- document.execCommand('copy');
- } catch (err) {
- this.setState({
- error: 'Oops, unable to copy'
- });
- }
- }
- }, {
key: "render",
value: function render() {
var _this$props$asset = this.props.asset,
@@ -134,31 +78,29 @@ function (_React$Component) {
label: _react.default.createElement(_Label.default, {
value: 'Share:'
}),
- content: _react.default.createElement(AssetShareButtons, {
+ content: _react.default.createElement(_AssetShareButtons.default, {
host: host,
+ name: name,
shortId: shortId
})
})), _react.default.createElement(_Row.default, null, _react.default.createElement(_RowLabeled.default, {
label: _react.default.createElement(_Label.default, {
value: 'Link:'
}),
- content: _react.default.createElement(ClickToCopy, {
+ content: _react.default.createElement(_ClickToCopy.default, {
id: 'short-link',
- value: "".concat(host, "/").concat(shortId, "/").concat(name, ".").concat(fileExt),
- copyToClipboard: this.copyToClipboard
+ value: "".concat(host, "/").concat(shortId, "/").concat(name, ".").concat(fileExt)
})
})), _react.default.createElement(_Row.default, null, _react.default.createElement(_RowLabeled.default, {
label: _react.default.createElement(_Label.default, {
value: 'Embed:'
}),
- content: _react.default.createElement("div", null, contentType === 'video/mp4' ? _react.default.createElement(ClickToCopy, {
+ content: _react.default.createElement("div", null, contentType === 'video/mp4' ? _react.default.createElement(_ClickToCopy.default, {
id: 'embed-text-video',
- value: ""),
- copyToClipboard: this.copyToClipboard
- }) : _react.default.createElement(ClickToCopy, {
+ value: "")
+ }) : _react.default.createElement(_ClickToCopy.default, {
id: 'embed-text-image',
- value: ""),
- copyToClipboard: this.copyToClipboard
+ value: "")
}))
})), _react.default.createElement(_Row.default, null, _react.default.createElement(_SpaceBetween.default, null, _react.default.createElement(_reactRouterDom.Link, {
className: "link--primary",
diff --git a/client/build/containers/PublishDisabledMessage/view.js b/client/build/containers/PublishDisabledMessage/view.js
index 24487939..7ef8f198 100644
--- a/client/build/containers/PublishDisabledMessage/view.js
+++ b/client/build/containers/PublishDisabledMessage/view.js
@@ -40,11 +40,15 @@ function (_React$Component) {
key: "render",
value: function render() {
var message = this.props.message;
- return _react.default.createElement("div", null, _react.default.createElement("p", {
+ return _react.default.createElement("div", {
+ className: 'publish-disabled-message'
+ }, _react.default.createElement("div", {
+ className: 'message'
+ }, _react.default.createElement("p", {
className: 'text--secondary'
}, "Publishing is currently disabled."), _react.default.createElement("p", {
className: 'text--secondary'
- }, message));
+ }, message)));
}
}]);
diff --git a/client/build/utils/metaTags.js b/client/build/utils/metaTags.js
index 34daa9e0..9713f663 100644
--- a/client/build/utils/metaTags.js
+++ b/client/build/utils/metaTags.js
@@ -101,9 +101,9 @@ var createAssetMetaTags = function createAssetMetaTags(_ref3) {
defaultThumbnail = _ref3.defaultThumbnail;
var claimData = asset.claimData;
var contentType = claimData.contentType;
- var embedUrl = "".concat(siteHost, "/").concat(claimData.claimId, "/").concat(claimData.name);
+ var videoEmbedUrl = "".concat(siteHost, "/video-embed/").concat(claimData.name, "/").concat(claimData.claimId);
var showUrl = "".concat(siteHost, "/").concat(claimData.claimId, "/").concat(claimData.name);
- var source = "".concat(siteHost, "/").concat(claimData.claimId, "/").concat(claimData.name, ".").concat(claimData.fileExt);
+ var source = "".concat(siteHost, "/asset/").concat(claimData.name, "/").concat(claimData.claimId);
var ogTitle = claimData.title || claimData.name;
var ogDescription = claimData.description || defaultDescription;
var ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);
@@ -154,7 +154,7 @@ var createAssetMetaTags = function createAssetMetaTags(_ref3) {
});
metaTags.push({
property: 'og:type',
- content: 'video'
+ content: 'video.other'
});
metaTags.push({
property: 'twitter:card',
@@ -162,7 +162,7 @@ var createAssetMetaTags = function createAssetMetaTags(_ref3) {
});
metaTags.push({
property: 'twitter:player',
- content: embedUrl
+ content: videoEmbedUrl
});
metaTags.push({
property: 'twitter:player:width',
diff --git a/client/scss/all.scss b/client/scss/all.scss
index 6675e5c5..e2da3336 100644
--- a/client/scss/all.scss
+++ b/client/scss/all.scss
@@ -40,6 +40,7 @@
@import 'containers/_dropzone';
@import 'containers/_publish-url-input';
@import 'containers/_publish-status';
+@import 'containers/_publish-disabled-message';
@import '_media-queries';
diff --git a/client/scss/containers/_publish-disabled-message.scss b/client/scss/containers/_publish-disabled-message.scss
new file mode 100644
index 00000000..66bdba7c
--- /dev/null
+++ b/client/scss/containers/_publish-disabled-message.scss
@@ -0,0 +1,11 @@
+.publish-disabled-message {
+ // fill the parent flex container
+ flex: 1 0 auto;
+ // be a flex container for children
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ .message {
+ text-align: center;
+ }
+}
diff --git a/client/src/components/AssetShareButtons/index.js b/client/src/components/AssetShareButtons/index.js
new file mode 100644
index 00000000..dfb0c0b9
--- /dev/null
+++ b/client/src/components/AssetShareButtons/index.js
@@ -0,0 +1,39 @@
+import React from 'react';
+import SpaceBetween from '@components/SpaceBetween';
+
+const AssetShareButtons = ({ host, name, shortId }) => {
+ return (
+
+
+ twitter
+
+
+ facebook
+
+
+ tumblr
+
+
+ reddit
+
+
+ );
+};
+
+export default AssetShareButtons;
diff --git a/client/src/components/ClickToCopy/index.jsx b/client/src/components/ClickToCopy/index.jsx
new file mode 100644
index 00000000..35b7dba8
--- /dev/null
+++ b/client/src/components/ClickToCopy/index.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+
+class ClickToCopy extends React.Component {
+ constructor (props) {
+ super(props);
+ this.copyToClipboard = this.copyToClipboard.bind(this);
+ }
+ copyToClipboard (event) {
+ const elementToCopy = event.target.id;
+ const element = document.getElementById(elementToCopy);
+ element.select();
+ try {
+ document.execCommand('copy');
+ } catch (err) {
+ this.setState({error: 'Oops, unable to copy'});
+ }
+ }
+ render () {
+ const {id, value} = this.props;
+ return (
+
+ );
+ }
+}
+
+export default ClickToCopy;
diff --git a/client/src/containers/AssetInfo/view.jsx b/client/src/containers/AssetInfo/view.jsx
index 12427c27..e251e81d 100644
--- a/client/src/containers/AssetInfo/view.jsx
+++ b/client/src/containers/AssetInfo/view.jsx
@@ -4,74 +4,10 @@ import Label from '@components/Label';
import RowLabeled from '@components/RowLabeled';
import Row from '@components/Row';
import SpaceBetween from '@components/SpaceBetween';
-
-const AssetShareButtons = ({ host, name, shortId }) => {
- return (
-
-
- twitter
-
-
- facebook
-
-
- tumblr
-
-
- reddit
-
-
- );
-};
-
-const ClickToCopy = ({id, value, copyToClipboard}) => {
- return (
-
- );
-};
+import AssetShareButtons from '@components/AssetShareButtons';
+import ClickToCopy from '@components/ClickToCopy';
class AssetInfo extends React.Component {
- constructor (props) {
- super(props);
- this.copyToClipboard = this.copyToClipboard.bind(this);
- }
- copyToClipboard (event) {
- console.log('event:', event);
- console.log('event.target:', event.target);
- console.log('event.target.id:', event.target.id);
- const elementToCopy = event.target.id;
- const element = document.getElementById(elementToCopy);
- element.select();
- try {
- document.execCommand('copy');
- } catch (err) {
- this.setState({error: 'Oops, unable to copy'});
- }
- }
render () {
const { asset: { shortId, claimData : { channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host } } } = this.props;
return (
@@ -99,6 +35,7 @@ class AssetInfo extends React.Component {
content={
}
@@ -114,7 +51,6 @@ class AssetInfo extends React.Component {
}
/>
@@ -131,13 +67,11 @@ class AssetInfo extends React.Component {
`}
- copyToClipboard={this.copyToClipboard}
/>
) : (
`}
- copyToClipboard={this.copyToClipboard}
/>
)}
diff --git a/client/src/containers/PublishDisabledMessage/view.jsx b/client/src/containers/PublishDisabledMessage/view.jsx
index b48271de..355ce75d 100644
--- a/client/src/containers/PublishDisabledMessage/view.jsx
+++ b/client/src/containers/PublishDisabledMessage/view.jsx
@@ -4,9 +4,11 @@ class PublishDisabledMessage extends React.Component {
render () {
const message = this.props.message;
return (
-
-
Publishing is currently disabled.
-
{message}
+
+
+
Publishing is currently disabled.
+
{message}
+
);
}
diff --git a/client/src/utils/metaTags.js b/client/src/utils/metaTags.js
index cd11b853..c5b9df34 100644
--- a/client/src/utils/metaTags.js
+++ b/client/src/utils/metaTags.js
@@ -46,9 +46,9 @@ const createChannelMetaTags = ({siteHost, siteTitle, siteTwitter, channel}) => {
const createAssetMetaTags = ({siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail}) => {
const { claimData } = asset;
const { contentType } = claimData;
- const embedUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`;
+ const videoEmbedUrl = `${siteHost}/video-embed/${claimData.name}/${claimData.claimId}`;
const showUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`;
- const source = `${siteHost}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`;
+ const source = `${siteHost}/asset/${claimData.name}/${claimData.claimId}`;
const ogTitle = claimData.title || claimData.name;
const ogDescription = claimData.description || defaultDescription;
const ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);
@@ -68,9 +68,9 @@ const createAssetMetaTags = ({siteHost, siteTitle, siteTwitter, asset, defaultDe
metaTags.push({property: 'og:video:type', content: contentType});
metaTags.push({property: 'og:image', content: ogThumbnail});
metaTags.push({property: 'og:image:type', content: ogThumbnailContentType});
- metaTags.push({property: 'og:type', content: 'video'});
+ metaTags.push({property: 'og:type', content: 'video.other'});
metaTags.push({property: 'twitter:card', content: 'player'});
- metaTags.push({property: 'twitter:player', content: embedUrl});
+ metaTags.push({property: 'twitter:player', content: videoEmbedUrl});
metaTags.push({property: 'twitter:player:width', content: 600});
metaTags.push({property: 'twitter:text:player_width', content: 600});
metaTags.push({property: 'twitter:player:height', content: 337});
diff --git a/index.js b/index.js
index fb4e362e..be30317c 100644
--- a/index.js
+++ b/index.js
@@ -35,6 +35,10 @@ const speechPassport = require('./server/speechPassport');
const {
details: { port: PORT },
auth: { sessionKey },
+ startup: {
+ performChecks,
+ performUpdates,
+ },
} = require('@config/siteConfig');
function Server () {
@@ -97,31 +101,70 @@ function Server () {
/* create server */
this.server = http.Server(this.app);
};
+ this.startServerListening = () => {
+ logger.info(`Starting server on ${PORT}...`);
+ return new Promise((resolve, reject) => {
+ this.server.listen(PORT, () => {
+ logger.info(`Server is listening on PORT ${PORT}`);
+ resolve();
+ })
+ });
+ };
this.syncDatabase = () => {
+ logger.info(`Syncing database...`);
return createDatabaseIfNotExists()
.then(() => {
db.sequelize.sync();
})
};
+ this.performChecks = () => {
+ if (!performChecks) {
+ return;
+ }
+ logger.info(`Performing checks...`);
+ return Promise.all([
+ getWalletBalance(),
+ ])
+ .then(([walletBalance]) => {
+ logger.info('Starting LBC balance:', walletBalance);
+ })
+ };
+ this.performUpdates = () => {
+ if (!performUpdates) {
+ return;
+ }
+ logger.info(`Peforming updates...`);
+ return Promise.all([
+ db.Blocked.refreshTable(),
+ db.Tor.refreshTable(),
+ ])
+ .then(([updatedBlockedList, updatedTorList]) => {
+ logger.info('Blocked list updated, length:', updatedBlockedList.length);
+ logger.info('Tor list updated, length:', updatedTorList.length);
+ })
+ };
this.start = () => {
this.initialize();
this.createApp();
this.createServer();
- /* start the server */
- logger.info('getting LBC balance & syncing database...');
- Promise.all([
- this.syncDatabase(),
- getWalletBalance(),
- ])
- .then(([syncResult, walletBalance]) => {
- logger.info('starting LBC balance:', walletBalance);
- return this.server.listen(PORT, () => {
- logger.info(`Server is listening on PORT ${PORT}`);
- })
+ this.syncDatabase()
+ .then(() => {
+ return this.startServerListening();
+ })
+ .then(() => {
+ return Promise.all([
+ this.performChecks(),
+ this.performUpdates(),
+ ])
+ })
+ .then(() => {
+ logger.info('Spee.ch startup is complete');
})
.catch(error => {
if (error.code === 'ECONNREFUSED') {
return logger.error('Connection refused. The daemon may not be running.')
+ } else if (error.code === 'EADDRINUSE') {
+ return logger.error('Server could not start listening. The port is already in use.');
} else if (error.message) {
logger.error(error.message);
}
diff --git a/server/controllers/api/blocked/index.js b/server/controllers/api/blocked/index.js
new file mode 100644
index 00000000..aad2dfc2
--- /dev/null
+++ b/server/controllers/api/blocked/index.js
@@ -0,0 +1,22 @@
+const logger = require('winston');
+const db = require('../../../models');
+
+const updateBlockedList = (req, res) => {
+ db.Blocked.refreshTable()
+ .then(data => {
+ logger.info('finished updating blocked content list');
+ res.status(200).json({
+ success: true,
+ data,
+ });
+ })
+ .catch(error => {
+ logger.error(error);
+ res.status(500).json({
+ success: false,
+ error,
+ });
+ });
+};
+
+module.exports = updateBlockedList;
diff --git a/server/controllers/api/claim/blockedList/index.js b/server/controllers/api/claim/blockedList/index.js
deleted file mode 100644
index abc80d8e..00000000
--- a/server/controllers/api/claim/blockedList/index.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const logger = require('winston');
-const db = require('../../../../models');
-
-const updateBlockedList = (req, res) => {
- return fetch('https://api.lbry.io/file/list_blocked')
- .then(response => {
- return response.json();
- })
- .then(jsonResponse => {
- if (!jsonResponse.data) {
- throw new Error('no data in list_blocked response');
- }
- if (!jsonResponse.data.outpoints) {
- throw new Error('no outpoints in list_blocked response');
- }
- return jsonResponse.data.outpoints;
- })
- .then(outpoints => {
- logger.info('number of blocked outpoints:', outpoints.length);
- let updatePromises = [];
- outpoints.forEach(outpoint => {
- // logger.debug('outpoint:', outpoint);
- updatePromises.push(db.Claim
- .findOne({
- where: {
- outpoint,
- },
- })
- .then(Claim => {
- if (Claim) {
- const { claimId, name } = Claim;
- logger.debug(`creating record in Blocked for ${name}#${claimId}`);
- const blocked = {
- claimId,
- name,
- outpoint,
- };
- return db.upsert(db.Blocked, blocked, blocked, 'Blocked')
- }
- })
- .catch(error => {
- logger.error(error);
- }));
- });
- return Promise.all(updatePromises);
- })
- .then(() => {
- logger.info('finished updating blocked content list');
- res.status(200).json({success: true, message: 'finished updating blocked content list'});
- })
- .catch((error) => {
- logger.error(error);
- });
-};
-
-module.exports = updateBlockedList;
diff --git a/server/controllers/api/claim/longId/index.js b/server/controllers/api/claim/longId/index.js
index 0eb3668c..27f66b1c 100644
--- a/server/controllers/api/claim/longId/index.js
+++ b/server/controllers/api/claim/longId/index.js
@@ -22,7 +22,10 @@ const claimLongId = ({ ip, originalUrl, body, params }, res) => {
getClaimId(channelName, channelClaimId, claimName, claimId)
.then(fullClaimId => {
claimId = fullClaimId;
- return db.Blocked.isNotBlocked(fullClaimId, claimName);
+ return db.Claim.getOutpoint(claimName, fullClaimId);
+ })
+ .then(outpoint => {
+ return db.Blocked.isNotBlocked(outpoint);
})
.then(() => {
res.status(200).json({success: true, data: claimId});
diff --git a/server/controllers/api/claim/publish/index.js b/server/controllers/api/claim/publish/index.js
index 15e48ee9..b429e797 100644
--- a/server/controllers/api/claim/publish/index.js
+++ b/server/controllers/api/claim/publish/index.js
@@ -1,4 +1,6 @@
-const { details: { host } } = require('@config/siteConfig');
+const logger = require('winston');
+
+const { details: { host }, publishing: { disabled, disabledMessage } } = require('@config/siteConfig');
const { sendGATimingEvent } = require('../../../../utils/googleAnalytics.js');
@@ -19,7 +21,20 @@ const authenticateUser = require('./authentication.js');
*/
-const claimPublish = ({ body, files, headers, ip, originalUrl, user }, res) => {
+const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res) => {
+ // logging
+ logger.info('Publish request:', {
+ ip,
+ headers,
+ body,
+ });
+ // check for disabled publishing
+ if (disabled) {
+ return res.status(503).json({
+ success: false,
+ message: disabledMessage
+ });
+ }
// define variables
let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title;
// record the start time of the request
diff --git a/server/controllers/api/config/site/publishing/index.js b/server/controllers/api/config/site/publishing/index.js
new file mode 100644
index 00000000..08e60bf3
--- /dev/null
+++ b/server/controllers/api/config/site/publishing/index.js
@@ -0,0 +1,29 @@
+const { publishing: {
+ primaryClaimAddress,
+ uploadDirectory,
+ thumbnailChannel,
+ thumbnailChannelId,
+ additionalClaimAddresses,
+ disabled,
+ disabledMessage
+} } = require('@config/siteConfig');
+
+/*
+
+ route to see if publishing is enabled
+
+*/
+
+const publishingConfig = (req, res) => {
+ return res.status(200).json({
+ primaryClaimAddress,
+ uploadDirectory,
+ thumbnailChannel,
+ thumbnailChannelId,
+ additionalClaimAddresses,
+ disabled,
+ disabledMessage
+ });
+};
+
+module.exports = publishingConfig;
diff --git a/server/controllers/api/tor/index.js b/server/controllers/api/tor/index.js
new file mode 100644
index 00000000..df4c5831
--- /dev/null
+++ b/server/controllers/api/tor/index.js
@@ -0,0 +1,25 @@
+const logger = require('winston');
+const db = require('../../../models');
+
+/*
+
+ Route to update and return tor exit nodes that can connect to this ip address
+
+*/
+
+const getTorList = (req, res) => {
+ db.Tor.refreshTable()
+ .then( result => {
+ logger.debug('number of records', result.length);
+ res.status(200).json(result);
+ })
+ .catch((error) => {
+ logger.error(error);
+ res.status(500).json({
+ success: false,
+ error,
+ })
+ });
+};
+
+module.exports = getTorList;
diff --git a/server/controllers/assets/constants/request_types.js b/server/controllers/assets/constants/request_types.js
new file mode 100644
index 00000000..22f0d0ce
--- /dev/null
+++ b/server/controllers/assets/constants/request_types.js
@@ -0,0 +1,9 @@
+const EMBED = 'EMBED';
+const BROWSER = 'BROWSER';
+const SOCIAL = 'SOCIAL';
+
+module.exports = {
+ EMBED,
+ BROWSER,
+ SOCIAL,
+};
diff --git a/server/controllers/assets/serveAsset/index.js b/server/controllers/assets/serveAsset/index.js
new file mode 100644
index 00000000..3f0149a8
--- /dev/null
+++ b/server/controllers/assets/serveAsset/index.js
@@ -0,0 +1,17 @@
+const { sendGAServeEvent } = require('../../../utils/googleAnalytics');
+const getClaimIdAndServeAsset = require('../utils/getClaimIdAndServeAsset.js');
+
+/*
+
+ route to serve an asset directly
+
+*/
+
+const serveAsset = ({ headers, ip, originalUrl, params: { claimName, claimId } }, res) => {
+ // send google analytics
+ sendGAServeEvent(headers, ip, originalUrl);
+ // get the claim Id and then serve the asset
+ getClaimIdAndServeAsset(null, null, claimName, claimId, originalUrl, ip, res);
+};
+
+module.exports = serveAsset;
diff --git a/server/controllers/assets/serveByClaim/index.js b/server/controllers/assets/serveByClaim/index.js
index a561754e..6e0e9e40 100644
--- a/server/controllers/assets/serveByClaim/index.js
+++ b/server/controllers/assets/serveByClaim/index.js
@@ -3,11 +3,10 @@ const handleShowRender = require('../../../render/build/handleShowRender.js');
const lbryUri = require('../utils/lbryUri.js');
-const determineResponseType = require('../utils/determineResponseType.js');
+const determineRequestType = require('../utils/determineRequestType.js');
const getClaimIdAndServeAsset = require('../utils/getClaimIdAndServeAsset.js');
-const logRequestData = require('../utils/logRequestData.js');
-const SERVE = 'SERVE';
+const { EMBED } = require('../constants/request_types.js');
/*
@@ -15,7 +14,7 @@ const SERVE = 'SERVE';
*/
-const serverAssetByClaim = (req, res) => {
+const serveByClaim = (req, res) => {
const { headers, ip, originalUrl, params } = req;
// decide if this is a show request
let hasFileExtension;
@@ -24,13 +23,11 @@ const serverAssetByClaim = (req, res) => {
} catch (error) {
return res.status(400).json({success: false, message: error.message});
}
- let responseType = determineResponseType(hasFileExtension, headers);
- if (responseType !== SERVE) {
+ // determine request type
+ let requestType = determineRequestType(hasFileExtension, headers);
+ if (requestType !== EMBED) {
return handleShowRender(req, res);
}
- // handle serve request
- // send google analytics
- sendGAServeEvent(headers, ip, originalUrl);
// parse the claim
let claimName;
try {
@@ -38,10 +35,10 @@ const serverAssetByClaim = (req, res) => {
} catch (error) {
return res.status(400).json({success: false, message: error.message});
}
- // log the request data for debugging
- logRequestData(responseType, claimName, null, null);
+ // send google analytics
+ sendGAServeEvent(headers, ip, originalUrl);
// get the claim Id and then serve the asset
getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);
};
-module.exports = serverAssetByClaim;
+module.exports = serveByClaim;
diff --git a/server/controllers/assets/serveByIdentifierAndClaim/index.js b/server/controllers/assets/serveByIdentifierAndClaim/index.js
index e493e01e..609a1256 100644
--- a/server/controllers/assets/serveByIdentifierAndClaim/index.js
+++ b/server/controllers/assets/serveByIdentifierAndClaim/index.js
@@ -3,12 +3,11 @@ const handleShowRender = require('../../../render/build/handleShowRender.js');
const lbryUri = require('../utils/lbryUri.js');
-const determineResponseType = require('../utils/determineResponseType.js');
+const determineRequestType = require('../utils/determineRequestType.js');
const getClaimIdAndServeAsset = require('../utils/getClaimIdAndServeAsset.js');
const flipClaimNameAndId = require('../utils/flipClaimNameAndId.js');
-const logRequestData = require('../utils/logRequestData.js');
-const SERVE = 'SERVE';
+const { EMBED } = require('../constants/request_types.js');
/*
@@ -16,22 +15,20 @@ const SERVE = 'SERVE';
*/
-const serverAssetByIdentifierAndClaim = (req, res) => {
+const serverByIdentifierAndClaim = (req, res) => {
const { headers, ip, originalUrl, params } = req;
- // decide if this is a show request
+ // parse request
let hasFileExtension;
try {
({ hasFileExtension } = lbryUri.parseModifier(params.claim));
} catch (error) {
return res.status(400).json({success: false, message: error.message});
}
- let responseType = determineResponseType(hasFileExtension, headers);
- if (responseType !== SERVE) {
+ // determine request type
+ let requestType = determineRequestType(hasFileExtension, headers);
+ if (requestType !== EMBED) {
return handleShowRender(req, res);
}
- // handle serve request
- // send google analytics
- sendGAServeEvent(headers, ip, originalUrl);
// parse the claim
let claimName;
try {
@@ -50,10 +47,10 @@ const serverAssetByIdentifierAndClaim = (req, res) => {
if (!isChannel) {
[claimId, claimName] = flipClaimNameAndId(claimId, claimName);
}
- // log the request data for debugging
- logRequestData(responseType, claimName, channelName, claimId);
+ // send google analytics
+ sendGAServeEvent(headers, ip, originalUrl);
// get the claim Id and then serve the asset
getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);
};
-module.exports = serverAssetByIdentifierAndClaim;
+module.exports = serverByIdentifierAndClaim;
diff --git a/server/controllers/assets/utils/determineRequestType.js b/server/controllers/assets/utils/determineRequestType.js
new file mode 100644
index 00000000..afc5574f
--- /dev/null
+++ b/server/controllers/assets/utils/determineRequestType.js
@@ -0,0 +1,60 @@
+const logger = require('winston');
+const { EMBED, BROWSER, SOCIAL } = require('../constants/request_types.js');
+
+function headersMatchesSocialBotList (headers) {
+ const userAgent = headers['user-agent'];
+ const socialBotList = [
+ 'facebookexternalhit',
+ 'Twitterbot',
+ ];
+ for (let i = 0; i < socialBotList.length; i++) {
+ if (userAgent.includes(socialBotList[i])) {
+ logger.debug('request is from social bot:', socialBotList[i]);
+ return true;
+ }
+ }
+ return false;
+}
+
+function clientAcceptsHtml ({accept}) {
+ return accept && accept.match(/text\/html/);
+}
+
+function requestIsFromBrowser (headers) {
+ return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);
+}
+
+function clientWantsAsset ({accept, range}) {
+ const imageIsWanted = accept && accept.match(/image\/.*/) && !accept.match(/text\/html/) && !accept.match(/text\/\*/);
+ const videoIsWanted = accept && range;
+ return imageIsWanted || videoIsWanted;
+}
+
+const determineRequestType = (hasFileExtension, headers) => {
+ let responseType;
+ logger.debug('headers:', headers);
+ // return early with 'show' if headers match the list
+ if (headersMatchesSocialBotList(headers)) {
+ return SOCIAL;
+ }
+ // if request is not from a social bot...
+ if (hasFileExtension) {
+ // assume embed,
+ responseType = EMBED;
+ // but change to browser if client accepts html.
+ if (clientAcceptsHtml(headers)) {
+ responseType = BROWSER;
+ }
+ // if request does not have file extentsion...
+ } else {
+ // assume browser,
+ responseType = BROWSER;
+ // but change to embed if someone embeded a show url...
+ if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) {
+ responseType = EMBED;
+ }
+ }
+ return responseType;
+};
+
+module.exports = determineRequestType;
diff --git a/server/controllers/assets/utils/determineResponseType.js b/server/controllers/assets/utils/determineResponseType.js
deleted file mode 100644
index f32a0c5c..00000000
--- a/server/controllers/assets/utils/determineResponseType.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const logger = require('winston');
-
-const SERVE = 'SERVE';
-const SHOW = 'SHOW';
-
-function clientAcceptsHtml ({accept}) {
- return accept && accept.match(/text\/html/);
-};
-
-function requestIsFromBrowser (headers) {
- return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);
-};
-
-function clientWantsAsset ({accept, range}) {
- const imageIsWanted = accept && accept.match(/image\/.*/) && !accept.match(/text\/html/) && !accept.match(/text\/\*/);
- const videoIsWanted = accept && range;
- return imageIsWanted || videoIsWanted;
-};
-
-const determineResponseType = (hasFileExtension, headers) => {
- let responseType;
- if (hasFileExtension) {
- responseType = SERVE; // assume a serve request if file extension is present
- if (clientAcceptsHtml(headers)) { // if the request comes from a browser, change it to a show request
- responseType = SHOW;
- }
- } else {
- responseType = SHOW;
- if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) { // this is in case someone embeds a show url
- logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');
- responseType = SERVE;
- }
- }
- return responseType;
-};
-
-module.exports = determineResponseType;
diff --git a/server/controllers/assets/utils/getClaimIdAndServeAsset.js b/server/controllers/assets/utils/getClaimIdAndServeAsset.js
index e391383d..6603d046 100644
--- a/server/controllers/assets/utils/getClaimIdAndServeAsset.js
+++ b/server/controllers/assets/utils/getClaimIdAndServeAsset.js
@@ -17,7 +17,12 @@ const getClaimIdAndServeAsset = (channelName, channelClaimId, claimName, claimId
getClaimId(channelName, channelClaimId, claimName, claimId)
.then(fullClaimId => {
claimId = fullClaimId;
- return db.Blocked.isNotBlocked(fullClaimId, claimName);
+ logger.debug('Full claim id:', fullClaimId);
+ return db.Claim.getOutpoint(claimName, fullClaimId);
+ })
+ .then(outpoint => {
+ logger.debug('Outpoint:', outpoint);
+ return db.Blocked.isNotBlocked(outpoint);
})
.then(() => {
return getLocalFileRecord(claimId, claimName);
diff --git a/server/controllers/pages/sendEmbedPage.js b/server/controllers/pages/sendVideoEmbedPage.js
similarity index 73%
rename from server/controllers/pages/sendEmbedPage.js
rename to server/controllers/pages/sendVideoEmbedPage.js
index d4bef437..01f6b1f4 100644
--- a/server/controllers/pages/sendEmbedPage.js
+++ b/server/controllers/pages/sendVideoEmbedPage.js
@@ -1,10 +1,10 @@
const { details: { host } } = require('@config/siteConfig');
-const sendEmbedPage = ({ params }, res) => {
+const sendVideoEmbedPage = ({ params }, res) => {
const claimId = params.claimId;
const name = params.name;
// get and render the content
res.status(200).render('embed', { layout: 'embed', host, claimId, name });
};
-module.exports = sendEmbedPage;
+module.exports = sendVideoEmbedPage;
diff --git a/server/lbrynet/index.js b/server/lbrynet/index.js
index bab4ede0..4ff64521 100644
--- a/server/lbrynet/index.js
+++ b/server/lbrynet/index.js
@@ -1,6 +1,6 @@
const axios = require('axios');
const logger = require('winston');
-const { apiHost, apiPort } = require('@config/lbryConfig');
+const { apiHost, apiPort, getTimeout } = require('@config/lbryConfig');
const lbrynetUri = 'http://' + apiHost + ':' + apiPort;
const { chooseGaLbrynetPublishLabel, sendGATimingEvent } = require('../utils/googleAnalytics.js');
const handleLbrynetResponse = require('./utils/handleLbrynetResponse.js');
@@ -31,7 +31,10 @@ module.exports = {
axios
.post(lbrynetUri, {
method: 'get',
- params: { uri, timeout: 20 },
+ params: {
+ uri,
+ timeout: getTimeout || 30,
+ },
})
.then(response => {
sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());
diff --git a/server/routes/utils/multipartMiddleware.js b/server/middleware/multipartMiddleware.js
similarity index 100%
rename from server/routes/utils/multipartMiddleware.js
rename to server/middleware/multipartMiddleware.js
diff --git a/server/middleware/torCheckMiddleware.js b/server/middleware/torCheckMiddleware.js
new file mode 100644
index 00000000..62c42af5
--- /dev/null
+++ b/server/middleware/torCheckMiddleware.js
@@ -0,0 +1,31 @@
+const logger = require('winston');
+const db = require('../models');
+
+const torCheck = (req, res, next) => {
+ const { ip } = req;
+ logger.debug(`tor check for: ${ip}`);
+ return db.Tor.findAll(
+ {
+ where: {
+ address: ip,
+ },
+ raw: true,
+ })
+ .then(result => {
+ if (result.length >= 1) {
+ logger.info('Tor request blocked:', ip);
+ const failureResponse = {
+ success: false,
+ message: 'Unfortunately this api route is not currently available for tor users. We are working on a solution that will allow tor users to use this endpoint in the future.',
+ };
+ res.status(403).json(failureResponse);
+ } else {
+ return next();
+ }
+ })
+ .catch(error => {
+ logger.error(error);
+ });
+};
+
+module.exports = torCheck;
diff --git a/server/models/blocked.js b/server/models/blocked.js
index 12a04ca9..5e413889 100644
--- a/server/models/blocked.js
+++ b/server/models/blocked.js
@@ -6,14 +6,6 @@ module.exports = (sequelize, { STRING }) => {
const Blocked = sequelize.define(
'Blocked',
{
- claimId: {
- type : STRING,
- allowNull: false,
- },
- name: {
- type : STRING,
- allowNull: false,
- },
outpoint: {
type : STRING,
allowNull: false,
@@ -24,13 +16,12 @@ module.exports = (sequelize, { STRING }) => {
}
);
- Blocked.isNotBlocked = function (claimId, name) {
- logger.debug(`checking to see if ${name}#${claimId} is not blocked`);
+ Blocked.isNotBlocked = function (outpoint) {
+ logger.debug(`checking to see if ${outpoint} is not blocked`);
return new Promise((resolve, reject) => {
this.findOne({
where: {
- claimId,
- name,
+ outpoint,
},
})
.then(result => {
@@ -46,5 +37,39 @@ module.exports = (sequelize, { STRING }) => {
});
};
+ Blocked.refreshTable = function () {
+ let blockedList = [];
+ return fetch('https://api.lbry.io/file/list_blocked')
+ .then(response => {
+ return response.json();
+ })
+ .then(jsonResponse => {
+ if (!jsonResponse.data) {
+ throw new Error('no data in list_blocked response');
+ }
+ if (!jsonResponse.data.outpoints) {
+ throw new Error('no outpoints in list_blocked response');
+ }
+ return jsonResponse.data.outpoints;
+ })
+ .then(outpoints => {
+ logger.debug('total outpoints:', outpoints.length);
+ // prep the records
+ for (let i = 0; i < outpoints.length; i++) {
+ blockedList.push({
+ outpoint: outpoints[i],
+ });
+ }
+ // clear the table
+ return this.destroy({
+ truncate: true,
+ });
+ })
+ .then(() => {
+ // fill the table
+ return this.bulkCreate(blockedList);
+ });
+ };
+
return Blocked;
};
diff --git a/server/models/claim.js b/server/models/claim.js
index 128d76ee..7e2a5f61 100644
--- a/server/models/claim.js
+++ b/server/models/claim.js
@@ -378,5 +378,27 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
});
};
+ Claim.getOutpoint = function (name, claimId) {
+ return this
+ .findAll({
+ where : { name, claimId },
+ attributes: ['outpoint'],
+ })
+ .then(result => {
+ logger.debug('outpoint result');
+ switch (result.length) {
+ case 0:
+ throw new Error(`no record found for ${name}#${claimId}`);
+ case 1:
+ return result[0].dataValues.outpoint;
+ default:
+ throw new Error(`more than one record found for ${name}#${claimId}`);
+ }
+ })
+ .catch(error => {
+ throw error;
+ });
+ };
+
return Claim;
};
diff --git a/server/models/index.js b/server/models/index.js
index e2011bc8..a13d58ec 100644
--- a/server/models/index.js
+++ b/server/models/index.js
@@ -8,6 +8,7 @@ const File = require('./file.js');
const Request = require('./request.js');
const User = require('./user.js');
const Blocked = require('./blocked.js');
+const Tor = require('./tor.js');
const {database, username, password} = require('@config/mysqlConfig');
if (!database || !username || !password) {
@@ -50,6 +51,7 @@ db['File'] = sequelize.import('File', File);
db['Request'] = sequelize.import('Request', Request);
db['User'] = sequelize.import('User', User);
db['Blocked'] = sequelize.import('Blocked', Blocked);
+db['Tor'] = sequelize.import('Tor', Tor);
// run model.association for each model in the db object that has an association
logger.info('associating db models...');
diff --git a/server/models/tor.js b/server/models/tor.js
new file mode 100644
index 00000000..a314e92d
--- /dev/null
+++ b/server/models/tor.js
@@ -0,0 +1,59 @@
+const logger = require('winston');
+const { details: { ipAddress } } = require('@config/siteConfig');
+
+module.exports = (sequelize, { STRING }) => {
+ const Tor = sequelize.define(
+ 'Tor',
+ {
+ address: {
+ type : STRING,
+ allowNull: false,
+ },
+ fingerprint: {
+ type : STRING,
+ allowNull: true,
+ },
+ },
+ {
+ freezeTableName: true,
+ }
+ );
+
+ Tor.refreshTable = function () {
+ let torList = [];
+ return fetch(`https://check.torproject.org/api/bulk?ip=${ipAddress}&port=80`)
+ .then(response => {
+ return response.json();
+ })
+ .then(jsonResponse => {
+ logger.debug('total tor nodes:', jsonResponse.length);
+ // prep the records
+ for (let i = 0; i < jsonResponse.length; i++) {
+ torList.push({
+ address : jsonResponse[i].Address,
+ fingerprint: jsonResponse[i].Fingerprint,
+ });
+ }
+ // clear the table
+ return this.destroy({
+ truncate: true,
+ });
+ })
+ .then(() => {
+ // fill the table
+ return this.bulkCreate(torList);
+ })
+ .then(() => {
+ // return the new table
+ return this.findAll({
+ attributes: ['address', 'fingerprint'],
+ raw : true,
+ });
+ })
+ .catch(error => {
+ throw error;
+ });
+ };
+
+ return Tor;
+};
diff --git a/server/routes/api/index.js b/server/routes/api/index.js
index 0aabd472..bb24e5b2 100644
--- a/server/routes/api/index.js
+++ b/server/routes/api/index.js
@@ -1,9 +1,12 @@
+// middleware
+const multipartMiddleware = require('../../middleware/multipartMiddleware');
+const torCheckMiddleware = require('../../middleware/torCheckMiddleware');
+// route handlers
const channelAvailability = require('../../controllers/api/channel/availability');
const channelClaims = require('../../controllers/api/channel/claims');
const channelData = require('../../controllers/api/channel/data');
const channelShortId = require('../../controllers/api/channel/shortId');
const claimAvailability = require('../../controllers/api/claim/availability');
-const claimBlockedList = require('../../controllers/api/claim/blockedList');
const claimData = require('../../controllers/api/claim/data/');
const claimGet = require('../../controllers/api/claim/get');
const claimList = require('../../controllers/api/claim/list');
@@ -13,27 +16,34 @@ const claimResolve = require('../../controllers/api/claim/resolve');
const claimShortId = require('../../controllers/api/claim/shortId');
const fileAvailability = require('../../controllers/api/file/availability');
const userPassword = require('../../controllers/api/user/password');
+const publishingConfig = require('../../controllers/api/config/site/publishing');
+const getTorList = require('../../controllers/api/tor');
+const getBlockedList = require('../../controllers/api/blocked');
-const multipartMiddleware = require('../utils/multipartMiddleware');
module.exports = (app) => {
// channel routes
- app.get('/api/channel/availability/:name', channelAvailability);
- app.get('/api/channel/short-id/:longId/:name', channelShortId);
- app.get('/api/channel/data/:channelName/:channelClaimId', channelData);
- app.get('/api/channel/claims/:channelName/:channelClaimId/:page', channelClaims);
+ app.get('/api/channel/availability/:name', torCheckMiddleware, channelAvailability);
+ app.get('/api/channel/short-id/:longId/:name', torCheckMiddleware, channelShortId);
+ app.get('/api/channel/data/:channelName/:channelClaimId', torCheckMiddleware, channelData);
+ app.get('/api/channel/claims/:channelName/:channelClaimId/:page', torCheckMiddleware, channelClaims);
// claim routes
- app.get('/api/claim/availability/:name', claimAvailability);
- app.get('/api/claim/blocked-list/', claimBlockedList);
- app.get('/api/claim/data/:claimName/:claimId', claimData);
- app.get('/api/claim/get/:name/:claimId', claimGet);
- app.get('/api/claim/list/:name', claimList);
- app.post('/api/claim/long-id', claimLongId);
- app.post('/api/claim/publish', multipartMiddleware, claimPublish);
- app.get('/api/claim/resolve/:name/:claimId', claimResolve);
- app.get('/api/claim/short-id/:longId/:name', claimShortId);
+ app.get('/api/claim/availability/:name', torCheckMiddleware, claimAvailability);
+ app.get('/api/claim/data/:claimName/:claimId', torCheckMiddleware, claimData);
+ app.get('/api/claim/get/:name/:claimId', torCheckMiddleware, claimGet);
+ app.get('/api/claim/list/:name', torCheckMiddleware, claimList);
+ app.post('/api/claim/long-id', torCheckMiddleware, claimLongId); // note: should be a 'get'
+ app.post('/api/claim/publish', torCheckMiddleware, multipartMiddleware, claimPublish);
+ app.get('/api/claim/resolve/:name/:claimId', torCheckMiddleware, claimResolve);
+ app.get('/api/claim/short-id/:longId/:name', torCheckMiddleware, claimShortId);
// file routes
- app.get('/api/file/availability/:name/:claimId', fileAvailability);
+ app.get('/api/file/availability/:name/:claimId', torCheckMiddleware, fileAvailability);
// user routes
- app.put('/api/user/password/', userPassword);
+ app.put('/api/user/password/', torCheckMiddleware, userPassword);
+ // configs
+ app.get('/api/config/site/publishing', torCheckMiddleware, publishingConfig);
+ // tor
+ app.get('/api/tor', torCheckMiddleware, getTorList);
+ // blocked
+ app.get('/api/blocked', torCheckMiddleware, getBlockedList);
};
diff --git a/server/routes/assets/index.js b/server/routes/assets/index.js
index 4e87d2dd..5d4f92d1 100644
--- a/server/routes/assets/index.js
+++ b/server/routes/assets/index.js
@@ -1,7 +1,9 @@
-const serveAssetByClaim = require('../../controllers/assets/serveByClaim');
-const serveAssetByIdentifierAndClaim = require('../../controllers/assets/serveByIdentifierAndClaim');
+const serveByClaim = require('../../controllers/assets/serveByClaim');
+const serveByIdentifierAndClaim = require('../../controllers/assets/serveByIdentifierAndClaim');
+const serveAsset = require('../../controllers/assets/serveAsset');
-module.exports = (app, db) => {
- app.get('/:identifier/:claim', serveAssetByIdentifierAndClaim);
- app.get('/:claim', serveAssetByClaim);
+module.exports = (app) => {
+ app.get('/asset/:claimName/:claimId/', serveAsset);
+ app.get('/:identifier/:claim', serveByIdentifierAndClaim);
+ app.get('/:claim', serveByClaim);
};
diff --git a/server/routes/pages/index.js b/server/routes/pages/index.js
index 2c62b1aa..2dff606b 100644
--- a/server/routes/pages/index.js
+++ b/server/routes/pages/index.js
@@ -1,5 +1,5 @@
const handlePageRequest = require('../../controllers/pages/sendReactApp');
-const handleEmbedRequest = require('../../controllers/pages/sendEmbedPage');
+const handleVideoEmbedRequest = require('../../controllers/pages/sendVideoEmbedPage');
const redirect = require('../../controllers/utils/redirect');
module.exports = (app) => {
@@ -10,5 +10,5 @@ module.exports = (app) => {
app.get('/popular', handlePageRequest);
app.get('/new', handlePageRequest);
app.get('/multisite', handlePageRequest);
- app.get('/embed/:claimId/:name', handleEmbedRequest); // route to send embedable video player (for twitter)
+ app.get('/video-embed/:name/:claimId', handleVideoEmbedRequest); // for twitter
};
diff --git a/test/test.html b/test/test.html
new file mode 100644
index 00000000..01a5d622
--- /dev/null
+++ b/test/test.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
Document
+
+
+
+
no identifier, no ending
+
+
no identifier, yes ending
+
+
yes identifier, no ending
+
+
yes identifier, yes ending
+
+
+