Merge pull request #1809 from jsbin/feature/reported-bins

Feature/reported bins
This commit is contained in:
Remy Sharp 2014-08-10 09:13:16 +01:00
commit 9ec07a83ca
14 changed files with 119 additions and 206 deletions

View File

@ -33,7 +33,7 @@
"getUserForForgotToken": "SELECT `ownership`.*, expires FROM `ownership` INNER JOIN `forgot_tokens` ON `name` = `owner_name` WHERE `token` = ? AND `forgot_tokens`.`expires` >= ?",
"setForgotToken": "INSERT INTO `forgot_tokens` (`owner_name`, `token`, `expires`, `created`) VALUES (?, ?, ?, ?)",
"deleteExpiredForgotToken": "DELETE FROM `forgot_tokens` WHERE `expires` <= ? OR `token`=? OR `owner_name`=?",
"reportBin": "UPDATE `sandbox` SET `reported`=? WHERE `url`=? AND `revision`=? AND `active`='y'",
"reportBin": "UPDATE `sandbox` SET `reported`=?, `active`='n' WHERE `url`=? AND `revision`=? AND `reported` IS NULL",
"updateBinData": "UPDATE `sandbox` SET `:field`=? WHERE `url`=? AND `revision`=?",
"updateOwnersData": "UPDATE `owners` SET `:field`=? WHERE `url`=? AND `revision`=?",
"updateOwnershipData": "UPDATE `ownership` SET `:field`=? WHERE `name`=?",

View File

@ -53,6 +53,14 @@ exports.NotFound = HTTPError.extend({
}
});
// Creates an error object for handling 404 responses.
exports.Reported = HTTPError.extend({
constructor: function NotFound(message) {
HTTPError.call(this, 404, message);
}
});
exports.BinNotFound = exports.NotFound.extend({
constructor: function BinNotFound(message) {
exports.NotFound.call(this, 404, message);

View File

@ -397,9 +397,9 @@ module.exports = Observable.extend({
return res.redirect(root);
}
return next(new errors.BinNotFound('Could not find bin: ' + req.params.bin));
} else if (!bin.active) {
} else if (!bin.active && bin.reported) {
metrics.increment('bin.404-reported');
return next(new errors.NotFound('Bin has been reported: ' + req.params.bin));
return next(new errors.Reported('Bin has been reported: ' + req.params.bin));
} else {
req.bin = bin;
next();
@ -807,10 +807,10 @@ module.exports = Observable.extend({
if (!result || err === 401) {
metrics.increment('bin.404');
return next(new errors.BinNotFound('Could not find bin: ' + req.params.bin));
} else if (!result.active) {
return next(new errors.NotFound('Could not find bin: ' + req.params.bin));
} else if (!result.active && result.reported) {
metrics.increment('bin.404-reported');
return next(new errors.NotFound('Bin has been reported: ' + req.params.bin));
return next(new errors.Reported('Bin has been reported: ' + req.params.bin));
} else {
var flag = undefsafe(result, 'metadata.flagged');
if (flag) {

View File

@ -25,22 +25,25 @@ module.exports = Observable.extend({
if (err instanceof errors.NotFound && req.accepts('html')) {
if (err instanceof errors.BinNotFound) {
return (new BinHandler(this.sandbox)).notFound(req, res, next);
return this.renderErrorPage('error', err, req, res);
// return (new BinHandler(this.sandbox)).notFound(req, res, next);
} else {
return this.renderErrorPage(err, req, res);
return this.renderErrorPage('error', err, req, res);
}
next(err);
} else if (err instanceof errors.HTTPError) {
return this.renderError(err, req, res);
// return this.renderError(err, req, res);
return this.renderErrorPage(err.status, err, req, res);
next(err);
}
next(err);
},
// Fall through handler for when no routes match.
notFound: function (req, res) {
var error = new errors.NotFound('Page Does Not Exist');
if (req.accepts('html') && (req.url.indexOf('/api/') !== 0)) {
this.renderErrorPage(error, req, res);
this.renderErrorPage('404', error, req, res);
} else {
this.renderError(error, req, res);
}
@ -53,7 +56,7 @@ module.exports = Observable.extend({
this.sendErrorReport(err, req);
if (req.accepts('html')) {
this.renderErrorPage(err, req, res);
this.renderErrorPage('error', err, req, res);
} else {
var error = new errors.HTTPError(500, 'Internal Server Error');
this.renderError(error, req, res);
@ -74,10 +77,12 @@ module.exports = Observable.extend({
}
},
renderErrorPage: function (err, req, res) {
renderErrorPage: function (view, err, req, res) {
var status = err.status || 500;
res.status(status).render('error', {
var views = ['error', 504, 502];
res.status(status).render(views.indexOf(view) !== -1 ? view : 'error', {
is_500: status !== 404, // Saves us having many error pages at the mo.
is_404: status === 404,
root: this.helpers.url('', true),

View File

@ -181,7 +181,12 @@ module.exports = function (app) {
});
next();
}, userHandler.updateLastSeen, binHandler.loadBin);
}, userHandler.updateLastSeen, binHandler.loadBin, function (req, res, next) {
if (req.bin) {
app.emit('bin:loaded', req);
}
next();
});
// track the logged in and logged out numbers
app.get('*', function (req, res, next) {
@ -555,7 +560,8 @@ module.exports = function (app) {
app.get('/:bin/:rev?/watch', tag('live'), binHandler.getBin);
app.get('/:bin/:rev?/embed', tag('embed'), binHandler.getBin);
app.post('/:bin/:rev?/report', binHandler.report);
// don't expose anymore - reporting goes through github
// app.post('/:bin/:rev?/report', binHandler.report);
// Use this handler to check for a user creating/claiming their own bin url.
// We use :url here to prevent loadBin() being called and returning a not

View File

@ -272,6 +272,6 @@ module.exports = {
return str;
},
binUrlLength: function (req) {
return undefsafe(req, 'session.user') ? 2 : 7;
return undefsafe(req, 'session.user') ? 2 : 11;
},
};

View File

@ -1,63 +1,30 @@
html {
background: rgb(250, 250, 250);
min-height: 100%;
}
body {
background: #fff;
padding: 0;
margin: 0;
font-family: sans-serif;
background: #3FA8C6;
background: -moz-linear-gradient(top, #3fa8c6 0%, #3fa8c6 0%, #399ab2 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3fa8c6), color-stop(0%,#3fa8c6), color-stop(100%,#399ab2));
background: -webkit-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
background: -o-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
background: -ms-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
background: linear-gradient(to bottom, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
background-color: #399AB2;
background-repeat: repeat-x;
color: #fff;
text-shadow: 0 1px 0 rgba(0,0,0,.3);
font-family: 'helvetica neue', sans-serif;
font-size: 18px;
color: #111111;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
margin: 40px auto;
max-width: 660px;
border-radius: 10px;
}
.wrapper {
width: 50%;
margin: 0 auto;
}
h1, h2, h3, h4, h5, h6 {
letter-spacing: -0.03em;
font-size: 2em;
}
a {
color: white;
text-decoration: none;
border-bottom: 1px solid #fff;
border-bottom: 1px solid rgba(255,255,255,0.7);
padding-bottom: 0.15em;
position: relative;
}
a:after {
content: '';
position: absolute;
height: 1px;
left: 0;
right: 0;
bottom: -2px;
background: rgba(0,0,0,.1);
}
a:hover {
color: #C0E3EC;
div.wrapper {
margin-left: 128px;
padding: 10px;
}
h1 {
text-align: left;
letter-spacing: -0.03em;
font-size: 2em;
margin: 0.667em 0 0;
padding-left: 0.5em;
}
h2 {
font-size: 1.5em;
}
small {
@ -67,76 +34,19 @@ small {
font-size: 0.667em;
}
p em {
font-style: none;
}
#welcome {
position: relative;
overflow: hidden;
padding-bottom: 1em;
padding-left: 20px;
}
#welcome > div {
padding-top: 1px;
}
#dave {
height: 128px;
float: left;
margin-top: 3em
user-drag: none;
-moz-user-select: none;
-webkit-user-drag: none;
}
#welcome > h2 {
margin-top: 0.5em;
padding-left: 0.5em;
margin-bottom: 0;
margin-top: 2em;
}
.bubble p {
line-height: 22px;
line-height: 1.4;
}
.bubble {
background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.1);
padding: 0.667em 1em;
position: relative;
}
.bubble:after {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 20px solid white;
border-right-color: inherit;
top: 50px;
left: -20px;
}
img {
z-index: 1;
-webkit-transition: -webkit-transform 2s ease-in-out;
-moz-transition: -moz-transform 2s ease-in-out;
-o-transition: -o-transform 2s ease-in-out;
-ms-transition: -ms-transform 2s ease-in-out;
transition: transform 2s ease-in-out;
position: relative;
}
img:active {
-webkit-transform: rotate(1440deg) scale(1.2);
-moz-transform: rotate(1440deg) scale(1.2);
-o-transform: rotate(1440deg) scale(1.2);
-ms-transform: rotate(1440deg) scale(1.2);
transform: rotate(1440deg) scale(1.2);
}
pre {
@ -148,50 +58,27 @@ pre {
border-radius: 3px;
}
@media screen and (max-width: 1200px) {
.wrapper {
width: 80%;
}
}
@media screen and (max-width: 768px) {
.wrapper {
@media screen and (max-width: 660px) {
html {
width: auto;
margin: 0;
}
#welcome {
margin-right: 2.5%;
}
}
@media screen and (max-width: 500px) {
.wrapper {
text-align: center;
}
#dave {
float: none;
}
#welcome {
padding: 0 1.5em;
margin: 0;
border-radius: 0;
background: #fff;
}
h1 {
text-align: center;
margin-bottom: 0;
padding-left: 0;
font-size: 1.8em;
margin: 0;
}
#welcome > h2 {
margin-bottom: 0.667em;
body {
margin: 10px auto;
padding: 10px;
}
.bubble {
text-align: center;
}
.bubble:after {
img {
display: none;
}
}
div.wrapper {
margin-left: 0;
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -14,12 +14,12 @@ function jsbinShowEdit(options) {
btn.id = 'edit-with-js-bin';
btn.href = path + (path.slice(-1) === '/' ? '' : '/') + 'edit';
btn.innerHTML = 'Edit in JS Bin <img src="' + options['static'] + '/images/favicon.png" width="16" height="16">';
doc.body.appendChild(btn);
doc.documentElement.appendChild(btn);
// Style button:
style.setAttribute('rel', 'stylesheet');
style.setAttribute('href', options['static'] + '/css/edit.css');
doc.getElementsByTagName('head')[0].appendChild(style);
doc.documentElement.appendChild(style);
// show / hide button:

View File

@ -6,16 +6,12 @@
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
</head>
<body>
<img id="dave" src="{{static}}/images/jsbin_static.png" alt="Dave, the JS Bin bot">
<div class="wrapper">
<img id="dave" src="{{static}}/images/jsbin_static.png" alt="Dave, the JS Bin bot">
<div id="welcome">
<h1>502: Dave's left the building</h1>
<div class="bubble">
<p>JS Bin isn't available right now. Someone should be working on it,
and you can check the current status on <a href="http://status.jsbin.com">status.jsbin.com</a>, but do feel free to <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20it%20looks%20like%20you're%20currently%20down%20(502).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a>.</p>
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this atrocity.</p>
</div>
</div>
<h1>502: Dave's left the building</h1>
<p>JS Bin isn't available right now. Someone should be working on it,
and you can check the current status on <a href="http://status.jsbin.com">status.jsbin.com</a>, but do feel free to <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20it%20looks%20like%20you're%20currently%20down%20(502).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a>.</p>
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this atrocity.</p>
</div>
</body>
</html>

View File

@ -6,16 +6,12 @@
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
</head>
<body>
<img id="dave" src="{{static}}/images/dave.min.svg" alt="Dave, the JS Bin bot">
<div class="wrapper">
<img id="dave" src="{{static}}/images/jsbin_static.png" alt="Dave, the JS Bin bot">
<div id="welcome">
<h1>504: Dave didn't come back quickly enough</h1>
<div class="bubble">
<p>This is embarrassing, you've asked for something and I've spent too long getting it. Maybe I got distracted by some pretty lights, but you'll never know.</p>
<p>Do check <a href="http://status.jsbin.com">status.jsbin.com</a>, but do <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20you're%20taking%20too%20long%20to%20respond%20to%20requests%20(504).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a> if this problem keeps happening.</p>
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this slackness.</p>
</div>
</div>
<h1>504: Dave didn't come back quickly enough</h1>
<p>This is embarrassing, you've asked for something and I've spent too long getting it. Maybe I got distracted by some pretty lights, but you'll never know.</p>
<p>Do check <a href="http://status.jsbin.com">status.jsbin.com</a>, but do <a href="https://twitter.com/intent/tweet?text=@js_bin%20love%20the%20service,%20but%20you're%20taking%20too%20long%20to%20respond%20to%20requests%20(504).%20I've%20checked%20status.jsbin%20but%20thought%20I'd%20give%20you%20a%20heads%20up.">ping @js_bin</a> if this problem keeps happening.</p>
<p>If you want to add details please add it to the <a href="http://github.com/jsbin/jsbin/issues">issues page</a> and add any additional information you can to help diagnose this slackness.</p>
</div>
</body>
</html>

View File

@ -2,40 +2,38 @@
<html>
<head>
<meta charset="utf-8" />
<title>Uh-oh Something Went Wrong</title>
<title>404: JS Bin not found</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
</head>
<body>
<img id="dave" src="{{static}}/images/dave.min.svg" alt="Dave, the JS Bin bot">
<div class="wrapper">
<img id="dave" src="{{static}}/images/logo.png" alt="Dave, the JS Bin bot">
<div id="welcome">
{{#is_404}}
<h1>This page isn't here :-(</h1>
<div class="bubble">
<p>How about heading back to the <a href="{{root}}">homepage</a>
instead? It's nice there and there are lots of things to click on.</p>
<p>If you think there is supposed to be something here that isn't
let us know via the <a href="http://github.com/jsbin/jsbin/issues">Issues page</a>.</p>
</div>
{{/is_404}}
{{#is_500}}<h1>Oh no!<br />Something went wrong!</h1>
<p class="bubble">But don't worry we're probably on the case. In the
meantime you could try refreshing the page, if that doesn't work
let us know by creating an issue on the <a href="http://github.com/jsbin/jsbin/issues">Issues page</a>.</p>
{{#if is_404}}
<h1>This page isn't here :-(</h1>
<p>How about heading back to the <a href="{{root}}">homepage</a>
instead? It's nice there and there are lots of things to click on.</p>
<p>If you think there is supposed to be something here that isn't
let us know via the <a href="http://github.com/jsbin/jsbin/issues">Issues page</a>.</p>
{{/if}}
{{#if is_500}}
<h1>Something went wrong!</h1>
<p>But don't worry we're probably on the case. In the
meantime you could try refreshing the page, if that doesn't work
let us know by creating an issue on the <a href="http://github.com/jsbin/jsbin/issues">issues page</a>.</p>
<!--
{{err}}
{{stack}}
-->
{{/is_500}}
</div>
{{#is_500}}
{{/if}}
{{#if is_500}}
<details>
<summary>The error: {{err}}</summary>
<pre>{{request.method}} {{request.url}}
{{stack}}</pre>
</details>
{{/is_500}}
{{/if}}
</div>
</body>
</html>

View File

@ -2,7 +2,7 @@
<div class="toppanel-column toppanel-column-first">
<a href="#" class="toppanel-hide" title="Close">Close welcome panel</a>
<a href="#" class="toppanel-logo">
<img src="{{static}}/images/dave.svg" alt="Welcome to JS Bin">
<img src="{{static}}/images/dave.min.svg" alt="Welcome to JS Bin">
</a>
<div class="toppanel-actions{{#unless home}} toppanel-actions-alone{{/unless}}">
<div>

16
views/reported.html Normal file
View File

@ -0,0 +1,16 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>JS Bin - reported content</title>
<link rel="stylesheet" type="text/css" href="{{static}}/css/static-page.css">
</head>
<body>
<img id="dave" src="{{static}}/images/dave.min.svg" height="128" alt="Dave, the JS Bin bot">
<div class="wrapper">
<h1>This bin has been reported</h1>
<p>This bin has been reported as suspicious in content, and has been forboden from being part of the web.</p>
<p>If you believe this to be a mistake, please raise an <a href="http://github.com/jsbin/jsbin/issues/new?title=Incorrectly reported bin&body=Bin url: {{root}}{{request.url}}">issue</a> and add any additional information you can to help diagnose this atrocity.</p>
</div>
</body>
</html>