Merge remote-tracking branch 'refs/remotes/origin/master' into db-datatypes-migration
This commit is contained in:
commit
64175e023c
21 changed files with 80 additions and 55 deletions
|
@ -15,7 +15,7 @@ spee.ch is a single-serving site that reads and publishes images and videos to a
|
|||
* clone this repo
|
||||
* run `npm install`
|
||||
* create your `speechConfig.js` file
|
||||
* copy `speechConfig_example.js` and name it `speechConfig.js`
|
||||
* copy `speechConfig.js.example` and name it `speechConfig.js`
|
||||
* replace the `null` values in the config file with the appropriate values for your environement
|
||||
* to start the server, from your command line run `node speech.js`
|
||||
* To run hot, use `nodemon` instead of `node`
|
||||
|
|
|
@ -2,14 +2,8 @@ const db = require('../models');
|
|||
const logger = require('winston');
|
||||
|
||||
module.exports = {
|
||||
authenticateChannelCredentials (skipAuth, channelName, userPassword) {
|
||||
authenticateChannelCredentials (channelName, userPassword) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// skip authentication if not needed
|
||||
if (skipAuth) {
|
||||
resolve(skipAuth);
|
||||
return;
|
||||
}
|
||||
// authentication
|
||||
const userName = channelName.substring(1);
|
||||
logger.debug(`authenticateChannelCredentials > channelName: ${channelName} username: ${userName} pass: ${userPassword}`);
|
||||
db.User
|
||||
|
@ -40,4 +34,12 @@ module.exports = {
|
|||
});
|
||||
});
|
||||
},
|
||||
authenticateOrSkip (skipAuth, channelName, channelPassword) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (skipAuth) {
|
||||
return resolve(true);
|
||||
}
|
||||
return resolve(module.exports.authenticateChannelCredentials(channelName, channelPassword));
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -36,24 +36,18 @@ module.exports = {
|
|||
handleRequestError: function (action, originalUrl, ip, error, res) {
|
||||
logger.error(`Request Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
|
||||
postToStats(action, originalUrl, ip, null, null, error);
|
||||
const errorStatusAndMessage = this.returnErrorMessageAndStatus(error);
|
||||
const [status, message] = this.returnErrorMessageAndStatus(error);
|
||||
res
|
||||
.status(errorStatusAndMessage[0])
|
||||
.render('requestError', {
|
||||
status : errorStatusAndMessage[0],
|
||||
message: errorStatusAndMessage[1],
|
||||
});
|
||||
.status(status)
|
||||
.render('requestError', this.createErrorResponsePayload(status, message));
|
||||
},
|
||||
handleApiError: function (action, originalUrl, ip, error, res) {
|
||||
logger.error(`Api ${action} Error on ${originalUrl}`, module.exports.useObjectPropertiesIfNoKeys(error));
|
||||
postToStats(action, originalUrl, ip, null, null, error);
|
||||
const errorStatusAndMessage = this.returnErrorMessageAndStatus(error);
|
||||
const [status, message] = this.returnErrorMessageAndStatus(error);
|
||||
res
|
||||
.status(errorStatusAndMessage[0])
|
||||
.json({
|
||||
success: false,
|
||||
message: errorStatusAndMessage[1],
|
||||
});
|
||||
.status(status)
|
||||
.json(this.createErrorResponsePayload(status, message));
|
||||
},
|
||||
useObjectPropertiesIfNoKeys: function (err) {
|
||||
if (Object.keys(err).length === 0) {
|
||||
|
@ -65,4 +59,11 @@ module.exports = {
|
|||
}
|
||||
return err;
|
||||
},
|
||||
createErrorResponsePayload (status, message) {
|
||||
return {
|
||||
status,
|
||||
success: false,
|
||||
message,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -130,7 +130,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
|||
where: {
|
||||
name : channelName,
|
||||
claimId: {
|
||||
[sequelize.Op.like]: `${channelId}%`,
|
||||
$like: `${channelId}%`,
|
||||
},
|
||||
},
|
||||
order: [['height', 'ASC']],
|
||||
|
|
|
@ -234,7 +234,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
|||
where: {
|
||||
name,
|
||||
claimId: {
|
||||
[sequelize.Op.like]: `${shortId}%`,
|
||||
$like: `${shortId}%`,
|
||||
}},
|
||||
order: [['height', 'ASC']],
|
||||
})
|
||||
|
|
|
@ -25,7 +25,6 @@ module.exports = (sequelize, { STRING }) => {
|
|||
};
|
||||
|
||||
User.prototype.comparePassword = function (password, callback) {
|
||||
logger.debug(`User.prototype.comparePassword ${password} ${this.password}`);
|
||||
bcrypt.compare(password, this.password, callback);
|
||||
};
|
||||
|
||||
|
|
|
@ -526,7 +526,7 @@ table {
|
|||
padding:6px;
|
||||
}
|
||||
|
||||
.show-asset-light {
|
||||
.showlite-asset {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
padding-right: 1.5em;
|
||||
}
|
||||
|
||||
.show-asset-light {
|
||||
.showlite-asset {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ function getRequest (url) {
|
|||
if ( xhttp.status == 200) {
|
||||
resolve(xhttp.response);
|
||||
} else if (xhttp.status == 401) {
|
||||
reject('Wrong username or password');
|
||||
reject('Wrong channel name or password');
|
||||
} else {
|
||||
reject('request failed with status:' + xhttp.status);
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ function postRequest (url, params) {
|
|||
if ( xhttp.status == 200) {
|
||||
resolve(xhttp.response);
|
||||
} else if (xhttp.status == 401) {
|
||||
reject( new AuthenticationError('Wrong username or password'));
|
||||
reject( new AuthenticationError('Wrong channel name or password'));
|
||||
} else {
|
||||
reject('request failed with status:' + xhttp.status);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var stagedFiles = null;
|
||||
|
||||
var publishFileFunctions = {
|
||||
const publishFileFunctions = {
|
||||
triggerFileChooser: function (fileInputId) {
|
||||
document.getElementById(fileInputId).click();
|
||||
},
|
||||
|
@ -182,7 +182,7 @@ var publishFileFunctions = {
|
|||
this.updateUploadPercent('<p>Curious what magic is happening here? <a class="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>');
|
||||
},
|
||||
showFilePublishFailure: function (msg){
|
||||
this.updatePublishStatus('<p>Something went wrong...</p><p>' + msg + '</p><strong>For help, post the above error text in the #speech channel on the <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">lbry discord</a></strong>');
|
||||
this.updatePublishStatus('<p>Something went wrong...</p><p><strong>' + msg + '</strong></p><p>For help, post the above error text in the #speech channel on the <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">lbry discord</a>');
|
||||
this.hidePublishProgressBar();
|
||||
this.hideUploadPercent();
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// validation function which checks the proposed file's type, size, and name
|
||||
var validationFunctions = {
|
||||
const validationFunctions = {
|
||||
validateFile: function (file) {
|
||||
if (!file) {
|
||||
console.log('no file found');
|
||||
|
|
|
@ -8,7 +8,7 @@ const { getClaimList, resolveUri } = require('../helpers/lbryApi.js');
|
|||
const { createPublishParams, validateApiPublishRequest, validatePublishSubmission, cleanseChannelName, checkClaimNameAvailability, checkChannelAvailability } = require('../helpers/publishHelpers.js');
|
||||
const errorHandlers = require('../helpers/errorHandlers.js');
|
||||
const { postToStats, sendGoogleAnalytics } = require('../controllers/statsController.js');
|
||||
const { authenticateChannelCredentials } = require('../auth/authentication.js');
|
||||
const { authenticateOrSkip } = require('../auth/authentication.js');
|
||||
|
||||
module.exports = (app) => {
|
||||
// route to run a claim_list request on the daemon
|
||||
|
@ -73,8 +73,6 @@ module.exports = (app) => {
|
|||
});
|
||||
// route to run a publish request on the daemon
|
||||
app.post('/api/publish', multipartMiddleware, ({ body, files, ip, originalUrl, user }, res) => {
|
||||
logger.debug('api/publish body:', body);
|
||||
logger.debug('api/publish body:', files);
|
||||
let file, fileName, filePath, fileType, name, nsfw, license, title, description, thumbnail, anonymous, skipAuth, channelName, channelPassword;
|
||||
// validate that mandatory parts of the request are present
|
||||
try {
|
||||
|
@ -125,11 +123,11 @@ module.exports = (app) => {
|
|||
}
|
||||
}
|
||||
channelName = cleanseChannelName(channelName);
|
||||
logger.debug(`name: ${name}, license: ${license} title: "${title}" description: "${description}" channelName: "${channelName}" channelPassword: "${channelPassword}" nsfw: "${nsfw}"`);
|
||||
logger.debug(`/api/publish > name: ${name}, license: ${license} title: "${title}" description: "${description}" channelName: "${channelName}" channelPassword: "${channelPassword}" nsfw: "${nsfw}"`);
|
||||
// check channel authorization
|
||||
authenticateChannelCredentials(skipAuth, channelName, channelPassword)
|
||||
.then(result => {
|
||||
if (!result) {
|
||||
authenticateOrSkip(skipAuth, channelName, channelPassword)
|
||||
.then(authenticated => {
|
||||
if (!authenticated) {
|
||||
throw new Error('Authentication failed, you do not have access to that channel');
|
||||
}
|
||||
// make sure the claim name is available
|
||||
|
|
|
@ -184,6 +184,7 @@ module.exports = (app) => {
|
|||
res.status(200).render('noChannel');
|
||||
} else if (!result.claims) { // channel found, but no claims
|
||||
res.status(200).render('channel', {
|
||||
layout : 'channel',
|
||||
channelName : result.channelName,
|
||||
longChannelId : result.longChannelId,
|
||||
shortChannelId: result.shortChannelId,
|
||||
|
@ -197,6 +198,7 @@ module.exports = (app) => {
|
|||
} else { // channel found, with claims
|
||||
const totalPages = determineTotalPages(result.claims.length);
|
||||
res.status(200).render('channel', {
|
||||
layout : 'channel',
|
||||
channelName : result.channelName,
|
||||
longChannelId : result.longChannelId,
|
||||
shortChannelId: result.shortChannelId,
|
||||
|
@ -224,9 +226,6 @@ module.exports = (app) => {
|
|||
logger.debug('file extension =', fileExtension);
|
||||
} else {
|
||||
method = SHOW;
|
||||
if (headers['accept'] && !headers['accept'].split(',').includes('text/html')) {
|
||||
method = SERVE;
|
||||
}
|
||||
}
|
||||
logger.debug('claim name = ', name);
|
||||
logger.debug('method =', method);
|
||||
|
|
30
views/layouts/channel.handlebars
Normal file
30
views/layouts/channel.handlebars
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Spee.ch</title>
|
||||
<link rel="stylesheet" href="/assets/css/reset.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/general.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/mediaQueries.css" type="text/css">
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@spee_ch" />
|
||||
<meta property="og:title" content="{{this.channelName}} on Spee.ch">
|
||||
<meta property="og:site_name" content="Spee.ch">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:image" content="https://spee.ch/assets/img/Speech_Logo_Main@OG-02.jpg">
|
||||
<meta property="og:url" content="http://spee.ch/{{this.channelName}}:{{this.longChannelId}}">
|
||||
<meta property="og:description" content="View images and videos from {{this.channelName}}">
|
||||
<!--google font-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">
|
||||
<!-- google analytics -->
|
||||
{{ googleAnalytics }}
|
||||
</head>
|
||||
<body id="channel-body">
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
<script src="/assets/js/navBarFunctions.js"></script>
|
||||
{{> navBar}}
|
||||
{{{ body }}}
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<body id="embed-video-player">
|
||||
|
||||
<style type="text/css">
|
||||
video {
|
||||
|
|
|
@ -9,19 +9,19 @@
|
|||
<link rel="stylesheet" href="/assets/css/general.css" type="text/css">
|
||||
<link rel="stylesheet" href="/assets/css/mediaQueries.css" type="text/css">
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@lbryio" />
|
||||
<meta property="og:title" content="spee.ch">
|
||||
<meta property="og:site_name" content="spee.ch">
|
||||
<meta name="twitter:site" content="@spee_ch" />
|
||||
<meta property="og:title" content="Spee.ch">
|
||||
<meta property="og:site_name" content="Spee.ch">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:image" content="https://spee.ch/assets/img/Speech_Logo_Main@OG-02.jpg">
|
||||
<meta property="og:url" content="http://spee.ch/">
|
||||
<meta property="og:description" content="Open-source, decentralized image and video hosting.">
|
||||
<meta property="og:description" content="Open-source, decentralized image and video sharing.">
|
||||
<!--google font-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">
|
||||
<!-- google analytics -->
|
||||
{{ googleAnalytics }}
|
||||
</head>
|
||||
<body>
|
||||
<body id="main-body">
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
<script src="/assets/js/validationFunctions.js"></script>
|
||||
<script src="/assets/js/publishFileFunctions.js"></script>
|
||||
|
|
|
@ -18,11 +18,8 @@
|
|||
<!-- google analytics -->
|
||||
{{ googleAnalytics }}
|
||||
</head>
|
||||
<body>
|
||||
<body id="show-body">
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
<script src="/assets/js/validationFunctions.js"></script>
|
||||
<script src="/assets/js/authFunctions.js"></script>
|
||||
<script src="/assets/js/loginFunctions.js"></script>
|
||||
<script src="/assets/js/navBarFunctions.js"></script>
|
||||
{{> navBar}}
|
||||
{{{ body }}}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<!-- google analytics -->
|
||||
{{ googleAnalytics }}
|
||||
</head>
|
||||
<body>
|
||||
<body id="showlite-body">
|
||||
{{{ body }}}
|
||||
<script src="/assets/js/showFunctions.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/assets/js/authFunctions.js"></script>
|
||||
<script type="text/javascript">
|
||||
// show or hide the channel selection tools
|
||||
function toggleChannel (selectedOption) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
|
||||
{{#ifConditional fileInfo.fileExt '===' '.gifv'}}
|
||||
<video class="show-asset-light" autoplay loop muted>
|
||||
<video class="showlite-asset" autoplay loop muted>
|
||||
<source src="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">
|
||||
{{!--fallback--}}
|
||||
Your browser does not support the <code>video</code> element.
|
||||
</video>
|
||||
{{else}}
|
||||
<video class="show-asset-light" controls id="video-player">
|
||||
<video class="showlite-asset" controls id="video-player">
|
||||
<source src="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">
|
||||
{{!--fallback--}}
|
||||
Your browser does not support the <code>video</code> element.
|
||||
|
@ -16,6 +16,6 @@
|
|||
<a class="link--primary fine-print" href="/{{fileInfo.claimId}}/{{fileInfo.name}}">hosted via spee<h</a>
|
||||
{{else}}
|
||||
<a href="/{{fileInfo.claimId}}/{{fileInfo.name}}">
|
||||
<img class="show-asset-lite" src="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" alt="{{fileInfo.fileName}}"/>
|
||||
<img class="showlite-asset" src="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" alt="{{fileInfo.fileName}}"/>
|
||||
</a>
|
||||
{{/ifConditional}}
|
Loading…
Add table
Reference in a new issue