From f57bd7bfda8cb345dfd6563050bf807d159257b0 Mon Sep 17 00:00:00 2001 From: Aaron Minnick Date: Mon, 17 Feb 2025 18:57:01 -0800 Subject: [PATCH 1/2] WIP --- app/app.js | 6 ++++-- app/endpoints/crawl.js | 4 ++-- app/endpoints/delete_event.js | 4 ++-- app/endpoints/events.js | 6 +++--- app/endpoints/ical.js | 10 +++++----- app/endpoints/manage_event.js | 2 +- app/endpoints/retrieve_event.js | 6 ++---- app/models/calDaily.js | 2 +- app/test/crawl_test.js | 2 +- services/nginx/conf.d/shift.conf | 3 ++- site/themes/s2b_hugo_theme/assets/js/cal/addevent.js | 8 ++++---- site/themes/s2b_hugo_theme/assets/js/cal/main.js | 4 ++-- 12 files changed, 29 insertions(+), 28 deletions(-) diff --git a/app/app.js b/app/app.js index ec68c1d1..99336c72 100644 --- a/app/app.js +++ b/app/app.js @@ -46,10 +46,12 @@ const endpoints = [ "retrieve_event" ]; -// host each of those endpoint files at a php-like url: +// TODO: check for hardcoded uses of .php across repo + +// host each of those endpoint files: // note: require() is synchronous. endpoints.forEach((ep) => { - const apipath = `/api/${ep}.php`; + const apipath = `/api/${ep}`; const endpoint = require(`./endpoints/${ep}.js`); if (endpoint.get) { app.get(apipath, endpoint.get); diff --git a/app/endpoints/crawl.js b/app/endpoints/crawl.js index 58346788..b529c6f5 100644 --- a/app/endpoints/crawl.js +++ b/app/endpoints/crawl.js @@ -3,8 +3,8 @@ * Used by web crawlers such as search engines. * * Expects an (optional) TIME id using url query parameter; ex: - * https://api.shift2bikes.org/api/crawl.php?id=15229 - * https://localhost:3080/api/crawl.php?id=1893 + * https://api.shift2bikes.org/api/crawl?id=15229 + * https://localhost:3080/api/crawl?id=1893 * * See also: * https://github.com/shift-org/shift-docs/blob/main/docs/CALENDAR_API.md#crawling-an-event diff --git a/app/endpoints/delete_event.js b/app/endpoints/delete_event.js index f8bad740..d69310f0 100644 --- a/app/endpoints/delete_event.js +++ b/app/endpoints/delete_event.js @@ -4,14 +4,14 @@ * * You can use curl to post json for testing. For example: * curl -k -H 'Content-Type: application/json' -X POST --data-binary \ - * "@delete_event.json" https://localhost:4443/api/delete_event.php + * "@delete_event.json" https://localhost:4443/api/delete_event * { * "id": "6245", * "secret": "example" * } * * If there was an error ( for example, if the id was missing or the event wasn't found ) - * returns http 400 "Bad Request" and a json error response (see errors.php) + * returns http 400 "Bad Request" and a json error response (see errors.php) // 735-TODO: does this file still exist? * */ const config = require("../config"); diff --git a/app/endpoints/events.js b/app/endpoints/events.js index d71b4027..99b67156 100644 --- a/app/endpoints/events.js +++ b/app/endpoints/events.js @@ -8,8 +8,8 @@ * &all=true ( to include soft deleted rides ) * * For example: - * http://localhost:3080/api/events.php?id=1893 - * https://localhost:4443/api/events.php?startdate=2023-03-19&enddate=2023-03-29 + * http://localhost:3080/api/events?id=1893 + * https://localhost:4443/api/events?startdate=2023-03-19&enddate=2023-03-29 * * In both cases it returns a list of events as a JSON object: * { @@ -146,5 +146,5 @@ function getEventRangeUrl(start, end) { // the start and end, filtered through date formatting // should be safe to use as is, otherwise see: encodeURIComponent() return config.site.url("api", - `events.php?startdate=${startdate}&enddate=${enddate}`); + `events?startdate=${startdate}&enddate=${enddate}`); // 735-TODO: validate } diff --git a/app/endpoints/ical.js b/app/endpoints/ical.js index e595bc55..f2372a48 100644 --- a/app/endpoints/ical.js +++ b/app/endpoints/ical.js @@ -7,10 +7,10 @@ * 'filename' customizes the name of the generated file ( the default name is in config.js. ) * ( the special name of "none" will not generate an attachment ) * - * https://localhost:4443/api/ical.php - * https://localhost:4443/api/ical.php?id=998 - * https://localhost:4443/api/ical.php?startdate=2023-05-25&enddate=2023-06-25 - * https://localhost:4443/api/ical.php?id=13&filename=triskaidekaphobia.ics + * https://localhost:4443/api/ical + * https://localhost:4443/api/ical?id=998 + * https://localhost:4443/api/ical?startdate=2023-05-25&enddate=2023-06-25 + * https://localhost:4443/api/ical?id=13&filename=triskaidekaphobia.ics * * See also: * AllEvents.md @@ -112,7 +112,7 @@ function getEventData(cal, id, start, end, includeDeleted) { * @see https://datatracker.ietf.org/doc/html/rfc5545#section-3.6.1 */ function respondWith(cal, res, filename, events) { - // note: the php sets includes utf8 in the content type but... + // note: the php sets includes utf8 in the content type but... // 735-TODO: does this comment make sense anymore? // according to https://en.wikipedia.org/wiki/ICalendar // its default utf8, and mime type should be used for anything different. res.setHeader(config.api.header, config.api.version); diff --git a/app/endpoints/manage_event.js b/app/endpoints/manage_event.js index 1842b363..0de48d8a 100644 --- a/app/endpoints/manage_event.js +++ b/app/endpoints/manage_event.js @@ -5,7 +5,7 @@ * * You can use curl to post some json for testing. For example: * curl -k -H 'Content-Type: application/json' -X POST --data-binary \ - * "@manageEvent.json" https://localhost:4443/api/manage_event.php + * "@manageEvent.json" https://localhost:4443/api/manage_event * * On success, it will return a summary of the events and its times. * If there is a problem, it returns a set of 'fieldErrors' ( see errors.js ) diff --git a/app/endpoints/retrieve_event.js b/app/endpoints/retrieve_event.js index 847cc882..5c1c7cbf 100644 --- a/app/endpoints/retrieve_event.js +++ b/app/endpoints/retrieve_event.js @@ -5,11 +5,11 @@ * Expects an calevent id (and optionally, its matching secret) using url query parameters. * * For example: - * https://localhost:3080/api/retrieve_event.php?id=595&secret=12e1c433836d6c92431ac71f1ff6dd97 + * https://localhost:3080/api/retrieve_event?id=595&secret=12e1c433836d6c92431ac71f1ff6dd97 * * On success, returns a json summary of event. * If there was an error ( for example, if the id was missing or the event wasn't found ) - * returns http 400 "Bad Request" with a json error response ( see errors.php ) + * returns http 400 "Bad Request" with a json error response ( see errors.php ) // 735-TODO: remove? does file exist? * * See also: * https://github.com/shift-org/shift-docs/blob/main/docs/CALENDAR_API.md#retrieving-public-event-data @@ -31,8 +31,6 @@ exports.get = function get(req, res, next) { } else if (evt.isDeleted()) { res.textError("Event was deleted"); } else { - // the php version didnt error on invalid secret; - // so this doesnt either ( private data is only returned with a valid secret ) const includePrivate = evt.isSecretValid(secret); if (!evt.isPublished() && !includePrivate) { // act exactly as if unpublished events don't exist diff --git a/app/models/calDaily.js b/app/models/calDaily.js index e541d3ed..28433539 100644 --- a/app/models/calDaily.js +++ b/app/models/calDaily.js @@ -254,7 +254,7 @@ class CalDaily { * @param statusMap a js Map containing {YYYY-MM-DD: dateStatus } * @return the promise of valid CalDaily(s) * - * @see: DateStatus.php, manage_event.php + * @see: DateStatus.php, manage_event.php // 735-TODO: do these files exist? delete or update to js versions? */ static reconcile(evt, statusMap, softDelete = true) { return CalDaily.getByEventID(evt.id).then((dailies) => { diff --git a/app/test/crawl_test.js b/app/test/crawl_test.js index 276cc885..6afaa8fc 100644 --- a/app/test/crawl_test.js +++ b/app/test/crawl_test.js @@ -18,7 +18,7 @@ describe("crawl testing", () => { // test: it("handles a simple get", function(done) { chai.request( app ) - .get('/api/crawl.php') + .get('/api/crawl.php') // 735-TODO: update tests and run specs .end(function (err, res) { expect(err).to.be.null; expect(res).to.have.status(200); diff --git a/services/nginx/conf.d/shift.conf b/services/nginx/conf.d/shift.conf index f0bf7cf5..36da6c41 100644 --- a/services/nginx/conf.d/shift.conf +++ b/services/nginx/conf.d/shift.conf @@ -32,6 +32,7 @@ server { # used for the per-ride "export link". # the client sends an id as a query parameter. + # 735-TODO: investigate use of .php in this file location = /api/ics.php { proxy_pass http://node:3080/api/ical.php; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -51,7 +52,7 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } - # note: app/app.js remaps incoming ".php" extensions to ".js" endpoints + # note: app/app.js remaps incoming ".php" extensions to ".js" endpoints // 735-TODO: update this comment location /api/ { # note the trailing slash on the proxy; that causes nginx to strip /api/ completely. proxy_pass http://node:3080/api/; diff --git a/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js b/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js index ee2e0eff..c1aa6c55 100644 --- a/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js +++ b/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js @@ -13,7 +13,7 @@ // TODO: loading spinner var opts = { type: 'GET', - url: '/api/retrieve_event.php?id=' + id + "&secret=" + secret, + url: '/api/retrieve_event?id=' + id + "&secret=" + secret, // 735-TODO: validate headers: { 'Api-Version': API_VERSION }, success: function(data) { data.secret = secret; @@ -183,7 +183,7 @@ data.append('json', JSON.stringify(postVars)); var opts = { type: 'POST', - url: '/api/manage_event.php', + url: '/api/manage_event', // 735-TODO: validate headers: { 'Api-Version': API_VERSION }, contentType: false, processData: false, @@ -238,7 +238,7 @@ } // munge the "file" errors to be "image" errors // so that the error message shows on proper line. - // tbd: we also change this in manage_event.php + // tbd: we also change this in manage_event.php // 735-TODO: does this comment make sense anymore? if (err.fields && err.fields.file && !err.fields.image) { err.fields.image = err.fields.file; } @@ -383,7 +383,7 @@ })); var opts = { type: 'POST', - url: '/api/delete_event.php', + url: '/api/delete_event', // 735-TODO: validate headers: { 'Api-Version': API_VERSION }, contentType: false, processData: false, diff --git a/site/themes/s2b_hugo_theme/assets/js/cal/main.js b/site/themes/s2b_hugo_theme/assets/js/cal/main.js index 42b44404..deece375 100755 --- a/site/themes/s2b_hugo_theme/assets/js/cal/main.js +++ b/site/themes/s2b_hugo_theme/assets/js/cal/main.js @@ -3,7 +3,7 @@ $(document).ready(function() { var container = $('#mustache-html'); function getEventHTML(options, callback) { - var url = '/api/events.php?'; + var url = '/api/events?'; // 735-TODO: validate if (options.id) { url += 'id=' + options.id; } else if (options.startdate && options.enddate) { @@ -51,7 +51,7 @@ $(document).ready(function() { value.contactLink = container.getContactLink(value.contact); value.shareLink = '/calendar/event-' + value.caldaily_id; - value.exportlink = '/api/ics.php?id=' + value.id; + value.exportlink = '/api/ics.php?id=' + value.id; // 735-TODO: validate groupedByDate[date].events.push(value); }); From f3c6168d74ad334d939db772def6dbc5575456e1 Mon Sep 17 00:00:00 2001 From: Aaron Minnick Date: Mon, 3 Mar 2025 17:52:04 -0800 Subject: [PATCH 2/2] WIP --- app/app.js | 2 -- app/endpoints/delete_event.js | 4 +-- app/endpoints/ical.js | 4 +-- app/endpoints/retrieve_event.js | 4 +-- app/models/calDaily.js | 2 +- netlify.toml | 29 ++++++++++++++++--- netlify.toml.example | 4 +-- services/nginx/conf.d/shift.conf | 6 ++-- .../s2b_hugo_theme/assets/js/cal/addevent.js | 1 - .../s2b_hugo_theme/assets/js/cal/config.js | 10 +++---- 10 files changed, 41 insertions(+), 25 deletions(-) diff --git a/app/app.js b/app/app.js index 99336c72..39500530 100644 --- a/app/app.js +++ b/app/app.js @@ -46,8 +46,6 @@ const endpoints = [ "retrieve_event" ]; -// TODO: check for hardcoded uses of .php across repo - // host each of those endpoint files: // note: require() is synchronous. endpoints.forEach((ep) => { diff --git a/app/endpoints/delete_event.js b/app/endpoints/delete_event.js index d69310f0..152a9766 100644 --- a/app/endpoints/delete_event.js +++ b/app/endpoints/delete_event.js @@ -10,8 +10,8 @@ * "secret": "example" * } * - * If there was an error ( for example, if the id was missing or the event wasn't found ) - * returns http 400 "Bad Request" and a json error response (see errors.php) // 735-TODO: does this file still exist? + * If there was an error (for example, if the id was missing or the event wasn't found) + * returns http 400 "Bad Request" and a json error response (see errors.js) * */ const config = require("../config"); diff --git a/app/endpoints/ical.js b/app/endpoints/ical.js index f2372a48..c9c08a49 100644 --- a/app/endpoints/ical.js +++ b/app/endpoints/ical.js @@ -112,9 +112,7 @@ function getEventData(cal, id, start, end, includeDeleted) { * @see https://datatracker.ietf.org/doc/html/rfc5545#section-3.6.1 */ function respondWith(cal, res, filename, events) { - // note: the php sets includes utf8 in the content type but... // 735-TODO: does this comment make sense anymore? - // according to https://en.wikipedia.org/wiki/ICalendar - // its default utf8, and mime type should be used for anything different. + // according to https://en.wikipedia.org/wiki/ICalendar its default utf8, and mime type should be used for anything different. res.setHeader(config.api.header, config.api.version); if (!filename || filename === "none") { res.setHeader('content-type', `text/plain`); diff --git a/app/endpoints/retrieve_event.js b/app/endpoints/retrieve_event.js index 5c1c7cbf..a75d7b90 100644 --- a/app/endpoints/retrieve_event.js +++ b/app/endpoints/retrieve_event.js @@ -8,8 +8,8 @@ * https://localhost:3080/api/retrieve_event?id=595&secret=12e1c433836d6c92431ac71f1ff6dd97 * * On success, returns a json summary of event. - * If there was an error ( for example, if the id was missing or the event wasn't found ) - * returns http 400 "Bad Request" with a json error response ( see errors.php ) // 735-TODO: remove? does file exist? + * If there was an error (for example, if the id was missing or the event wasn't found) + * returns http 400 "Bad Request" with a json error response ( see errors.js ) * * See also: * https://github.com/shift-org/shift-docs/blob/main/docs/CALENDAR_API.md#retrieving-public-event-data diff --git a/app/models/calDaily.js b/app/models/calDaily.js index 28433539..b13e8e81 100644 --- a/app/models/calDaily.js +++ b/app/models/calDaily.js @@ -254,7 +254,7 @@ class CalDaily { * @param statusMap a js Map containing {YYYY-MM-DD: dateStatus } * @return the promise of valid CalDaily(s) * - * @see: DateStatus.php, manage_event.php // 735-TODO: do these files exist? delete or update to js versions? + * @see: dateStatus.js, manage_event.js */ static reconcile(evt, statusMap, softDelete = true) { return CalDaily.getByEventID(evt.id).then((dailies) => { diff --git a/netlify.toml b/netlify.toml index 929b3692..94adfe45 100644 --- a/netlify.toml +++ b/netlify.toml @@ -85,21 +85,42 @@ [[redirects]] from = "/cal/icalpp.php" - to = "https://api.shift2bikes.org/api/pedalpalooza-calendar.php" + to = "https://api.shift2bikes.org/api/pedalpalooza-calendar" status = 200 force = true ## the official pedalpalooza feed [[redirects]] from = "/cal/pedalpalooza-calendar.php" - to = "https://api.shift2bikes.org/api/pedalpalooza-calendar.php" + to = "https://api.shift2bikes.org/api/pedalpalooza-calendar" status = 200 force = true ## the official "all events" feed. [[redirects]] from = "/cal/shift-calendar.php" - to = "https://api.shift2bikes.org/api/shift-calendar.php" + to = "https://api.shift2bikes.org/api/shift-calendar" + status = 200 + force = true + +## 735-TODO: these because app may try to reach these endpoints at www. instead of api. - can solve with regex combining with the above? +[[redirects]] + from = "/cal/icalpp" + to = "https://api.shift2bikes.org/api/pedalpalooza-calendar" + status = 200 + force = true + +## the official pedalpalooza feed +[[redirects]] + from = "/cal/pedalpalooza-calendar" + to = "https://api.shift2bikes.org/api/pedalpalooza-calendar" + status = 200 + force = true + +## the official "all events" feed. +[[redirects]] + from = "/cal/shift-calendar" + to = "https://api.shift2bikes.org/api/shift-calendar" status = 200 force = true @@ -132,7 +153,7 @@ to = "/pages/pedalpalooza" status = 301 -## old bike rack webpage linked from PBoT and other offsite pages we can't fix +## old bike rack webpage linked from PBoT and other offsite pages we can't fix [[redirects]] from = "/wiki/shift-shop:rack-rental" to = "/pages/bike-racks/" diff --git a/netlify.toml.example b/netlify.toml.example index bfaa2447..e3646603 100644 --- a/netlify.toml.example +++ b/netlify.toml.example @@ -80,7 +80,7 @@ [[redirects]] from = "/my/specialpath" - to = "https://api.primarydomain.org/api/pedalpalooza-calendar.php" + to = "https://api.primarydomain.org/api/pedalpalooza-calendar" status = 200 force = true @@ -88,7 +88,7 @@ ## you'll probably want this somewhere on your ite! [[redirects]] from = "/allevents" - to = "https://api.primarydomain.org/api/shift-calendar.php" + to = "https://api.primarydomain.org/api/shift-calendar" status = 200 force = true diff --git a/services/nginx/conf.d/shift.conf b/services/nginx/conf.d/shift.conf index 36da6c41..e5cc79a5 100644 --- a/services/nginx/conf.d/shift.conf +++ b/services/nginx/conf.d/shift.conf @@ -34,7 +34,7 @@ server { # the client sends an id as a query parameter. # 735-TODO: investigate use of .php in this file location = /api/ics.php { - proxy_pass http://node:3080/api/ical.php; + proxy_pass http://node:3080/api/ical; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } @@ -42,13 +42,13 @@ server { # ex. webcal://www.shift2bikes.org/cal/pedalpalooza-calendar.php location = /api/pedalpalooza-calendar.php { # set to a constant range for this year's pedalp - proxy_pass http://node:3080/api/ical.php?startdate=2024-06-01&enddate=2024-08-31&filename=pedalpalooza-2024.ics; + proxy_pass http://node:3080/api/ical?startdate=2024-06-01&enddate=2024-08-31&filename=pedalpalooza-2024.ics; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # webcal endpoint for that includes all shift events: location = /api/shift-calendar.php { - proxy_pass http://node:3080/api/ical.php; + proxy_pass http://node:3080/api/ical; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } diff --git a/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js b/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js index a485aecd..ab33a475 100644 --- a/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js +++ b/site/themes/s2b_hugo_theme/assets/js/cal/addevent.js @@ -243,7 +243,6 @@ } // munge the "file" errors to be "image" errors // so that the error message shows on proper line. - // tbd: we also change this in manage_event.php // 735-TODO: does this comment make sense anymore? if (err.fields && err.fields.file && !err.fields.image) { err.fields.image = err.fields.file; } diff --git a/site/themes/s2b_hugo_theme/assets/js/cal/config.js b/site/themes/s2b_hugo_theme/assets/js/cal/config.js index 191e67c6..9927bb8d 100644 --- a/site/themes/s2b_hugo_theme/assets/js/cal/config.js +++ b/site/themes/s2b_hugo_theme/assets/js/cal/config.js @@ -3,11 +3,11 @@ const SITE_TITLE = "Shift"; const API_VERSION = '3'; const API_BASE_URL = window.location.origin; -const API_EVENTS_URL = new URL('/api/events.php', API_BASE_URL); -const API_ICS_URL = new URL('/api/ics.php', API_BASE_URL); -const API_MANAGE_URL = new URL('/api/manage_event.php', API_BASE_URL); -const API_RETRIEVE_URL = new URL('/api/retrieve_event.php', API_BASE_URL); -const API_DELETE_URL = new URL('/api/delete_event.php', API_BASE_URL); +const API_EVENTS_URL = new URL('/api/events', API_BASE_URL); +const API_ICS_URL = new URL('/api/ics', API_BASE_URL); +const API_MANAGE_URL = new URL('/api/manage_event', API_BASE_URL); +const API_RETRIEVE_URL = new URL('/api/retrieve_event', API_BASE_URL); +const API_DELETE_URL = new URL('/api/delete_event', API_BASE_URL); const API_HEADERS = { 'Accept': 'application/json',