diff --git a/.env.example b/.env.example index 3cf40d5..31085cd 100644 --- a/.env.example +++ b/.env.example @@ -7,7 +7,4 @@ CIPHER_PASSWORD=TEMP_PASSWORD ECOSYSTEM_SECRET=astringthatisactually32byteslong ECOSYSTEM_KEY=astringthatisactually32byteslong FLICKR_API_KEY=fake_key -UNSPLASH_APP_NAME=canvas-rce-api-dev -UNSPLASH_APP_ID=fake_app_id -UNSPLASH_SECRET=fake_secret YOUTUBE_API_KEY=fake_key \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 38652ca..70af491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +remove unsplash code + ## [1.24] Fix malformed URI error for search diff --git a/README.md b/README.md index 08173e7..401e823 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,6 @@ docker run \ -e ECOSYSTEM_KEY \ -e ECOSYSTEM_SECRET \ -e FLICKR_API_KEY \ - -e UNSPLASH_APP_ID \ - -e UNSPLASH_SECRET \ - -e UNSPLASH_APP_NAME \ -e YOUTUBE_API_KEY \ -e STATSD_PORT=8125 \ -e STATSD_HOST=127.0.0.1 \ @@ -68,9 +65,6 @@ Configuration options are set via the following environment variables: - `ECOSYSTEM_KEY`: _Required_ The encryption secret shared with Canvas. - `ECOSYSTEM_SECRET`: _Required_ The signing secret shared with Canvas. - `FLICKR_API_KEY`: Required to support Flickr image search. -- `UNSPLASH_APP_ID`: Required to support [Unsplash](https://unsplash.com) image search. -- `UNSPLASH_SECRET`: Required to support [Unsplash](https://unsplash.com) image search. -- `UNSPLASH_APP_NAME`: Required to support [Unsplash](https://unsplash.com) image search. - `YOUTUBE_API_KEY`: Required for querying titles of YouTube embeds. - `NODE_ENV`: This should always be set to `production` when running in production. diff --git a/app.js b/app.js index 5554f76..06df891 100644 --- a/app.js +++ b/app.js @@ -1,8 +1,7 @@ "use strict"; require("dotenv").config(); -// unsplash-js requires fetch to be available in the global scope -// see: https://github.com/unsplash/unsplash-js#adding-polyfills + global.fetch = require("node-fetch"); const container = require("./app/container"); diff --git a/app/api/index.js b/app/api/index.js index e571273..e80bb0f 100644 --- a/app/api/index.js +++ b/app/api/index.js @@ -4,7 +4,6 @@ const { actionKeyMiddleware: statsdKey } = require("../middleware/stats"); const _auth = require("../middleware/auth"); const wrapCanvas = require("./wrapCanvas"); const flickrSearch = require("./flickrSearch"); -const UnsplashController = require("./unsplash"); const getSessionHandler = require("./session"); const announcements = require("./announcements"); const assignments = require("./assignments"); @@ -26,10 +25,10 @@ const youTubeTitle = require("./youTubeApi"); const documents = require("./documents"); function inject() { - return [_auth, UnsplashController]; + return [_auth]; } -function init(auth, unsplashController) { +function init(auth) { return { applyToApp(app) { app.get( @@ -123,18 +122,7 @@ function init(auth, unsplashController) { auth, flickrSearch ); - app.get( - "/api/unsplash/search", - statsdKey("api", "unsplash_search"), - auth, - unsplashController.search.bind(unsplashController) - ); - app.get( - "/api/unsplash/pingback", - statsdKey("api", "unsplash_pingback"), - auth, - unsplashController.pingback.bind(unsplashController) - ); + app.get( "/api/session", statsdKey("api", "session"), diff --git a/app/api/unsplash.js b/app/api/unsplash.js deleted file mode 100644 index 680c78f..0000000 --- a/app/api/unsplash.js +++ /dev/null @@ -1,98 +0,0 @@ -"use strict"; - -const toJson = require("unsplash-js").toJson; -const _unsplash = require("../services/unsplash"); -const _env = require("../env"); - -class UnsplashController { - static inject() { - return [_unsplash, _env]; - } - - static init(unsplash, env) { - return new UnsplashController(unsplash, env); - } - - constructor(unsplash, env) { - this.unsplash = unsplash; - this.env = env; - } - - transformSearchResults(results) { - const transformedResults = { - total_results: results.total, - total_pages: results.total_pages, - results: results.results.map(imageResult => ({ - urls: { - link: imageResult.urls.regular, - thumbnail: imageResult.urls.thumb - }, - id: imageResult.id, - alt_text: imageResult.alt_description, - user: { - name: imageResult.user.name, - avatar: imageResult.user.profile_image.small, - url: `${imageResult.user.links.html}?utm_source=${this.env.get( - "UNSPLASH_APP_NAME", - () => "canvas-rce-api-dev" - )}&utm_medium=referral` - } - })) - }; - return transformedResults; - } - - async search(req, res) { - const searchTerm = req.query.term; - const page = req.query.page || undefined; // Unsplash defaults to page 1 - const perPage = req.query.per_page || undefined; // Unsplash defaults to 10 - try { - const searchResults = await this.unsplash.search.photos( - searchTerm, - page, - perPage, - { - contentFilter: "high" - } - ); - const jsonified = await toJson(searchResults); - res.send(this.transformSearchResults(jsonified)); - } catch (e) { - // TODO: better error handling - process.stderr.write("Unsplash Search Failed"); - process.stderr.write("" + e); - res.status(500).send("Internal Error, see server logs"); - } - } - - async pingback(req, res) { - const imageId = req.query.id; - // Doing this manually rather than using the Unsplash SDK saves us - // an extra request since the SDK requires doing an initial get request - // prior to then doing a "download" request. - try { - await global.fetch( - `https://api.unsplash.com/photos/${imageId}/download`, - { - headers: { - Authorization: `Client-ID ${this.env.get( - "UNSPLASH_APP_ID", - () => "fake_app_id" - )}` - } - } - ); - // The Unsplash API gives back an image URL, but it's unnecessary so - // we just send back an OK response with no body to save a few bytes - // across the wire. - res.status(200).send(); - } catch (e) { - // TODO: better error handling - process.stderr.write("Unsplash Pingback (Download) Failed"); - process.stderr.write("" + e); - res.status(500).send("Internal Error, see server logs"); - } - } -} - -module.exports = UnsplashController; diff --git a/app/services/unsplash.js b/app/services/unsplash.js deleted file mode 100644 index b98b926..0000000 --- a/app/services/unsplash.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -const Unsplash = require("unsplash-js").default; -const _env = require("../env"); - -function inject() { - return [_env]; -} - -function init(env) { - return new Unsplash({ - accessKey: env.get("UNSPLASH_APP_ID", () => "fake_app_id"), - secret: env.get("UNSPLASH_SECRET", () => "fake_secret") - }); -} - -module.exports = { inject, init }; diff --git a/package-lock.json b/package-lock.json index 09bf09f..2dc83d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,8 +28,7 @@ "parse-link-header": "0.4.1", "qs": "^6.2.1", "querystring": "0.2.0", - "raven": "github:zwily/raven-node#middleware-req-callback", - "unsplash-js": "^6.3.0" + "raven": "github:zwily/raven-node#middleware-req-callback" }, "devDependencies": { "cross-env": "^3.1.3", @@ -11364,17 +11363,6 @@ "node": ">=0.10.0" } }, - "node_modules/unsplash-js": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/unsplash-js/-/unsplash-js-6.3.0.tgz", - "integrity": "sha512-AmypERf7MIXYWBdoIYnofgB6DFoZgXhQST+K29T+S4ePVvzYqqrHxfiZosdqvb6Y15h6xCzEd/NqyG+99yk9xA==", - "dependencies": { - "form-urlencoded": "1.2.0", - "lodash.get": "4.4.2", - "querystring": "0.2.0", - "url-parse": "1.4.5" - } - }, "node_modules/unzip-response": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", @@ -20741,17 +20729,6 @@ } } }, - "unsplash-js": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/unsplash-js/-/unsplash-js-6.3.0.tgz", - "integrity": "sha512-AmypERf7MIXYWBdoIYnofgB6DFoZgXhQST+K29T+S4ePVvzYqqrHxfiZosdqvb6Y15h6xCzEd/NqyG+99yk9xA==", - "requires": { - "form-urlencoded": "1.2.0", - "lodash.get": "4.4.2", - "querystring": "0.2.0", - "url-parse": "1.4.5" - } - }, "unzip-response": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", diff --git a/package.json b/package.json index 4b92732..4148158 100644 --- a/package.json +++ b/package.json @@ -86,8 +86,7 @@ "parse-link-header": "0.4.1", "qs": "^6.2.1", "querystring": "0.2.0", - "raven": "github:zwily/raven-node#middleware-req-callback", - "unsplash-js": "^6.3.0" + "raven": "github:zwily/raven-node#middleware-req-callback" }, "devDependencies": { "cross-env": "^3.1.3", diff --git a/test/service/api/unsplash.test.js b/test/service/api/unsplash.test.js deleted file mode 100644 index 36be94a..0000000 --- a/test/service/api/unsplash.test.js +++ /dev/null @@ -1,177 +0,0 @@ -"use strict"; - -const UnsplashController = require("../../../app/api/unsplash"); -const sinon = require("sinon"); -const assert = require("assert"); -const nock = require("nock"); - -describe("Unsplash", () => { - let unsplashController; - let fakeUnsplash; - beforeEach(() => { - fakeUnsplash = { - search: { - photos() { - return Promise.resolve({ - ok: true, - json: () => ({ - total: 2285, - total_pages: 2285, - results: [ - { - id: "nKC772R_qog", - created_at: "2018-06-23T14:40:01-04:00", - updated_at: "2019-06-07T01:05:38-04:00", - width: 2853, - height: 3803, - color: "#060807", - description: - "little cat, \r\nThank you all who downloaded this lovely cat for the likes", - alt_description: "brown tabby kitten sitting on floor", - urls: { - raw: - "https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjY4MTA0fQ", - full: - "https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjY4MTA0fQ", - regular: - "https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjY4MTA0fQ", - small: - "https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjY4MTA0fQ", - thumb: - "https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjY4MTA0fQ" - }, - links: { - self: "https://api.unsplash.com/photos/nKC772R_qog", - html: "https://unsplash.com/photos/nKC772R_qog", - download: - "https://unsplash.com/photos/nKC772R_qog/download", - download_location: - "https://api.unsplash.com/photos/nKC772R_qog/download" - }, - categories: [], - sponsored: false, - sponsored_by: null, - sponsored_impressions_id: null, - likes: 112, - liked_by_user: false, - current_user_collections: [], - user: { - id: "oL6UyT-6pwA", - updated_at: "2019-06-06T03:12:06-04:00", - username: "edgaredgar", - name: "Edgar Edgar", - first_name: "Edgar", - last_name: "Edgar", - twitter_username: null, - portfolio_url: null, - bio: null, - location: null, - links: { - self: "https://api.unsplash.com/users/edgaredgar", - html: "https://unsplash.com/@edgaredgar", - photos: - "https://api.unsplash.com/users/edgaredgar/photos", - likes: "https://api.unsplash.com/users/edgaredgar/likes", - portfolio: - "https://api.unsplash.com/users/edgaredgar/portfolio", - following: - "https://api.unsplash.com/users/edgaredgar/following", - followers: - "https://api.unsplash.com/users/edgaredgar/followers" - }, - profile_image: { - small: - "https://images.unsplash.com/profile-1530270598334-93244e0a01a0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32", - medium: - "https://images.unsplash.com/profile-1530270598334-93244e0a01a0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=64&w=64", - large: - "https://images.unsplash.com/profile-1530270598334-93244e0a01a0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=128&w=128" - }, - instagram_username: null, - total_collections: 0, - total_likes: 9, - total_photos: 3, - accepted_tos: true - } - } - ] - }) - }); - } - } - }; - const fakeEnv = { - get: envVar => { - switch (envVar) { - case "UNSPLASH_APP_ID": - return "fake_app_id"; - case "UNSPLASH_APP_NAME": - return "fake_app_name"; - } - } - }; - unsplashController = UnsplashController.init(fakeUnsplash, fakeEnv); - }); - - describe("search", () => { - it("returns appropriately formatted data from the unsplash api", async () => { - const fakeRequest = { - query: { term: "some cool image" } - }; - const fakeResponse = { - send: sinon.spy(), - status: sinon.stub().returnsThis() - }; - - await unsplashController.search(fakeRequest, fakeResponse); - assert.ok( - fakeResponse.send.calledWith({ - total_results: 2285, - total_pages: 2285, - results: [ - { - urls: { - link: - "https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjY4MTA0fQ", - thumbnail: - "https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjY4MTA0fQ" - }, - id: "nKC772R_qog", - alt_text: "brown tabby kitten sitting on floor", - user: { - name: "Edgar Edgar", - avatar: - "https://images.unsplash.com/profile-1530270598334-93244e0a01a0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32", - url: - "https://unsplash.com/@edgaredgar?utm_source=fake_app_name&utm_medium=referral" - } - } - ] - }) - ); - }); - }); - - describe("pingback", () => { - it("calls the unsplash API download url with the proper id when called", async () => { - const scope = nock("https://api.unsplash.com") - .get("/photos/123/download") - .reply(200, "success"); - const fakeRequest = { - query: { - id: 123 - } - }; - const fakeResponse = { - status: sinon.stub().returnsThis(), - send: sinon.spy() - }; - await unsplashController.pingback(fakeRequest, fakeResponse); - assert.ok(scope.isDone(), "request was properly made to unsplash"); - assert.ok( - fakeResponse.status.calledWith(200), - "request sends back 200 status code" - ); - }); - }); -});