Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

added DMCA notice to shot page #2709

Merged
merged 2 commits into from Apr 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions server/db-patches/patch-15-16.sql
@@ -0,0 +1,2 @@
CREATE TYPE shot_block_type AS ENUM ('none', 'dmca');
ALTER TABLE data ADD COLUMN block_type shot_block_type DEFAULT 'none' NOT NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I would have used NULL as not-blocked, but I suppose this is fine too.

2 changes: 2 additions & 0 deletions server/db-patches/patch-16-15.sql
@@ -0,0 +1,2 @@
ALTER TABLE data DROP COLUMN block_type;
DROP TYPE shot_block_type;
2 changes: 1 addition & 1 deletion server/src/dbschema.js
Expand Up @@ -4,7 +4,7 @@ const pgpatcher = require("pg-patcher");
const path = require("path");
const mozlog = require("mozlog")("dbschema");

const MAX_DB_LEVEL = exports.MAX_DB_LEVEL = 15;
const MAX_DB_LEVEL = exports.MAX_DB_LEVEL = 16;

exports.forceDbVersion = function(version) {
mozlog.info("forcing-db-version", {db: db.constr, version});
Expand Down
2 changes: 2 additions & 0 deletions server/src/pages/shot/model.js
Expand Up @@ -34,6 +34,7 @@ exports.createModel = function(req) {
cspNonce: req.cspNonce,
hashAnalytics: true,
userAgent: req.headers['user-agent'],
blockType: req.shot.blockType,
downloadUrl,
isMobile
};
Expand Down Expand Up @@ -61,6 +62,7 @@ exports.createModel = function(req) {
defaultExpiration: req.config.defaultExpiration * 1000,
hashAnalytics: true,
userAgent: req.headers['user-agent'],
blockType: req.shot.blockType,
downloadUrl,
isMobile
};
Expand Down
9 changes: 4 additions & 5 deletions server/src/pages/shot/server.js
Expand Up @@ -11,13 +11,12 @@ exports.app = app;
app.get("/:id/:domain", csrf({cookie: true}), function(req, res) {
let shotId = `${req.params.id}/${req.params.domain}`;
Shot.get(req.backend, shotId).then((shot) => {
let noSuchShot = false;
if (!shot) {
noSuchShot = true;
} else if (shot.clipNames().length === 0 && !shot.deleted) {
let noSuchShot = !shot;
const nonOwnerAndBlocked = shot && shot.blockType !== 'none' && req.deviceId != shot.ownerId;
if (shot.clipNames().length === 0 && !shot.deleted) {
// Deleted shots always appear to have no clips
}
if (noSuchShot) {
if (noSuchShot || nonOwnerAndBlocked) {
notFound(req, res);
return;
}
Expand Down
32 changes: 32 additions & 0 deletions server/src/pages/shot/view.js
Expand Up @@ -194,12 +194,44 @@ class Body extends React.Component {
}

render() {
if (this.props.blockType !== 'none') {
return this.renderBlock();
}
if (this.props.expireTime !== null && Date.now() > this.props.expireTime) {
return this.renderExpired();
}
return this.renderBody();
}

renderBlock() {
let message = null;
let moreInfo = null;
if (this.props.blockType === 'dmca') {
if (this.props.isOwner) {
message = "This shot is no longer available due to an intellectual property claim.";
moreInfo = (
<span>
Please email <a href="mailto:dmcanotice@mozilla.com">dmcanotice@mozilla.com</a> to request further information. If your Shots are subject to multiple claims, we may revoke your access to Firefox Screenshots.<br/>
Please include the URL of this shot in your email: {this.props.backend}/{this.props.id}
</span>
);
}
}

return <reactruntime.BodyTemplate {...this.props}>
<div className="column-center full-height inverse-color-scheme">
<div className="large-icon-message-container">
<div className="large-icon logo" />
<div className="large-icon-message-string">
{ message }
<br/>
{ moreInfo }
</div>
</div>
</div>
</reactruntime.BodyTemplate>;
}

renderExpired() {
let expireTime = this.props.expireTime;
if (typeof expireTime != "number") {
Expand Down
7 changes: 5 additions & 2 deletions server/src/servershot.js
Expand Up @@ -307,6 +307,7 @@ Shot.getRawBytesForClip = function(uid) {
JOIN data ON images.shotid = data.id
WHERE images.id = $1
AND (data.expire_time IS NULL OR data.expire_time > NOW())
AND data.block_type = 'none'
AND NOT data.deleted`, [uid]
).then((rows) => {
if (!rows.length) {
Expand Down Expand Up @@ -375,6 +376,7 @@ Shot.get = function(backend, id, deviceId) {
shot.urlIfDeleted = rawValue.url;
shot.expireTime = rawValue.expireTime;
shot.deleted = rawValue.deleted;
shot.blockType = rawValue.blockType;
return shot;
});
};
Expand Down Expand Up @@ -403,7 +405,7 @@ Shot.getRawValue = function(id, deviceId) {
if (!id) {
throw new Error("Empty id: " + id);
}
let query = `SELECT value, deviceid, url, title, expire_time, deleted FROM data WHERE id = $1`;
let query = `SELECT value, deviceid, url, title, expire_time, deleted, block_type FROM data WHERE id = $1`;
let params = [id];
if (deviceId) {
query += ` AND deviceid = $2`;
Expand All @@ -423,7 +425,8 @@ Shot.getRawValue = function(id, deviceId) {
url: row.url,
title: row.title,
expireTime: row.expire_time,
deleted: row.deleted
deleted: row.deleted,
blockType: row.block_type
};
});
};
Expand Down