diff --git a/app/controllers/venue.js b/app/controllers/venue.js index 9c11ac57..66980e14 100644 --- a/app/controllers/venue.js +++ b/app/controllers/venue.js @@ -15,23 +15,26 @@ class VenueController extends SiteController { async start ( ) { const { limiter: limiterService } = this.dtp.services; - const welcomeLimiter = limiterService.createMiddleware(limiterService.config.welcome); const router = express.Router(); router.use(this.dtp.services.venue.channelMiddleware()); - this.dtp.app.use('/venue', welcomeLimiter, async (req, res, next) => { + this.dtp.app.use('/venue', async (req, res, next) => { res.locals.currentView = 'venue'; return next(); }, router); - router.get('/', this.getVenueView.bind(this)); + router.get( + '/', + limiterService.createMiddleware(limiterService.config.venue.getVenueEmbed), + this.getVenueEmbed.bind(this), + ); return router; } - async getVenueView (req, res) { + async getVenueEmbed (req, res) { res.render('venue/embed'); } } diff --git a/app/services/venue.js b/app/services/venue.js index 681402c3..1bde8e3e 100644 --- a/app/services/venue.js +++ b/app/services/venue.js @@ -4,6 +4,7 @@ 'use strict'; +const https = require('https'); const fetch = require('node-fetch'); // jshint ignore:line const CACHE_DURATION = 60 * 5; @@ -14,6 +15,14 @@ class VenueService extends SiteService { constructor (dtp) { super(dtp, module.exports); + this.soapboxDomain = process.env.DTP_SOAPBOX_HOST || 'shing.tv'; + } + + async start ( ) { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; + this.httpsAgent = new https.Agent({ + rejectUnauthorized: false, + }); } channelMiddleware ( ) { @@ -22,12 +31,12 @@ class VenueService extends SiteService { if (!res.locals.site || !res.locals.site.shingChannelSlug) { return next(); } - res.locals.shingChannelFeed = await this.getChannelFeed(res.locals.site.shingChannelSlug, { allowCache: true }); - res.locals.shingChannelStatus = await this.getChannelStatus(res.locals.site.shingChannelSlug, { allowCache: true }); + res.locals.shingChannelFeed = await this.getChannelFeed(res.locals.site.shingChannelSlug, { allowCache: false }); + res.locals.shingChannelStatus = await this.getChannelStatus(res.locals.site.shingChannelSlug, { allowCache: false }); this.log.debug('channel status', { status: res.locals.shingChannelStatus }); return next(); } catch (error) { - this.log.error('failed to populate Shing.tv channel feed', { error }); + this.log.error('failed to populate Soapbox channel feed', { error }); return next(); } }; @@ -44,8 +53,11 @@ class VenueService extends SiteService { if (json) { return json; } } - this.log.info('fetching Shing channel feed', { channelSlug }); - const response = await fetch(`https://shing.tv/channel/${channelSlug}/feed/json`); + const requestUrl = `https://${this.soapboxDomain}/channel/${channelSlug}/feed/json`; + this.log.info('fetching Shing channel feed', { channelSlug, requestUrl }); + const response = await fetch(requestUrl, { + agent: this.httpsAgent, + }); if (!response.ok) { throw new SiteError(500, 'Failed to fetch Shing channel feed'); } @@ -67,8 +79,11 @@ class VenueService extends SiteService { if (json) { return json; } } - this.log.info('fetching Shing channel status', { channelSlug }); - const response = await fetch(`https://shing.tv/channel/${channelSlug}/status`); + const requestUrl = `https://${this.soapboxDomain}/channel/${channelSlug}/status`; + this.log.info('fetching Shing channel status', { channelSlug, requestUrl }); + const response = await fetch(requestUrl, { + agent: this.httpsAgent, + }); if (!response.ok) { throw new SiteError(500, 'Failed to fetch Shing channel status'); } diff --git a/app/views/components/page-sidebar.pug b/app/views/components/page-sidebar.pug index 04c0a3a2..570c8589 100644 --- a/app/views/components/page-sidebar.pug +++ b/app/views/components/page-sidebar.pug @@ -9,10 +9,14 @@ mixin renderSidebarEpisode(episode) a(href= episode.url, target="_blank", title="Watch on Gab TV") img(src=episode.image).responsive - .uk-card-body - .uk-card-title.uk-margin-remove.uk-text-truncate - a(href= episode.url, target="_blank", title= `Watch "${episode.title}" on Gab TV`)= episode.title - .uk-text-small Posted: #{moment(episode.date_modified).format("MMM DD YYYY HH:MM a")} + a( + href= episode.url, + uk-tooltip=`Watch ${episode.title} on Gab TV`, + target="_blank", + ).uk-link-reset.uk-display-block + .uk-card-body + .uk-text-bold.uk-text-truncate= episode.title + .uk-text-small= moment(episode.date_modified).format("MMM DD YYYY HH:MM a") mixin renderPageSidebar ( ) //- @@ -64,12 +68,14 @@ mixin renderPageSidebar ( ) ul.uk-list each item in shingChannelFeed.items.slice(0, 3) li - a(href= item.url).uk-display-block + a(href= item.url, uk-tooltip=`Watch ${item.title} on Shing.tv`).uk-link-reset.uk-display-block .uk-card.uk-card-default.uk-card-small - img(src= item.image.url).responsive + img(src= item.image.url, width="640", height="360", alt=`Thumbnail image for ${item.title}`).responsive .uk-card-body .uk-text-bold.uk-text-truncate= item.title - .uk-text-small!= item.summary + .uk-text-small= moment(item.date_modified).format("MMM DD YYYY hh:mm a") + //- .uk-text-small!= item.summary + pre= JSON.stringify(item, null, 2) //- //- Gab TV channel integration //- diff --git a/app/views/venue/embed.pug b/app/views/venue/embed.pug index 3c0c4ff5..f4c6f8fb 100644 --- a/app/views/venue/embed.pug +++ b/app/views/venue/embed.pug @@ -1,6 +1,5 @@ extends ../layouts/main block content - //- - var shingBaseUrl = (process.env.NODE_ENV === 'production') ? 'https://shing.tv' : 'http://localhost:3333'; - - var shingBaseUrl = 'https://shing.tv'; + - var shingBaseUrl = `https://${dtp.services.venue.soapboxDomain}`; iframe(src= `${shingBaseUrl}/channel/${site.shingChannelSlug}/embed/venue?k=${site.shingWidgetKey}`, style="width: 100%; height: 720px;", allowfullscreen) \ No newline at end of file diff --git a/config/limiter.js b/config/limiter.js index 139202c8..25cb8ce1 100644 --- a/config/limiter.js +++ b/config/limiter.js @@ -353,6 +353,17 @@ module.exports = { }, }, + /* + * VenueController + */ + venue: { + getVenueEmbed: { + total: 20, + expire: ONE_MINUTE, + message: 'You are loading Venue too quickly. Please try again later.', + }, + }, + welcome: { total: 12, expire: ONE_MINUTE, diff --git a/dtp-sites.js b/dtp-sites.js index 04266c41..e0efc57f 100644 --- a/dtp-sites.js +++ b/dtp-sites.js @@ -16,11 +16,18 @@ module.rootPath = __dirname; module.pkg = require(path.join(module.rootPath, 'package.json')); module.config = { environment: process.env.NODE_ENV, - root: module.rootPath, component: DTP_COMPONENT, + root: module.rootPath, site: require(path.join(module.rootPath, 'config', 'site')), http: require(path.join(module.rootPath, 'config', 'http')), https: require(path.join(module.rootPath, 'config', 'https')), + registerMiddleware: async (dtp, app) => { + + module.log.info('registering Page service middleware'); + const { page: pageService } = module.services; + app.use(pageService.menuMiddleware.bind(pageService)); + + }, }; module.log = new SiteLog(module, module.config.component); @@ -66,4 +73,4 @@ module.shutdown = async ( ) => { process.exit(-1); } -})(); +})(); \ No newline at end of file diff --git a/lib/site-platform.js b/lib/site-platform.js index 44c20e7c..4cbd4139 100644 --- a/lib/site-platform.js +++ b/lib/site-platform.js @@ -202,7 +202,6 @@ module.exports.startPlatform = async (dtp) => { }; module.exports.startWebServer = async (dtp) => { - const { page: pageService } = module.services; const IS_PRODUCTION = (process.env.NODE_ENV === 'production'); dtp.app = module.app = express(); @@ -343,9 +342,7 @@ module.exports.startWebServer = async (dtp) => { module.app.use(async (req, res, next) => { const { cache: cacheService } = dtp.services; try { - res.locals.dtp = { - request: req, - }; + // expect incoming change from Base const settingsKey = `settings:${dtp.config.site.domainKey}:site`; res.locals.site = Object.assign({ }, dtp.config.site); @@ -360,7 +357,6 @@ module.exports.startWebServer = async (dtp) => { return next(error); } }); - module.app.use(pageService.menuMiddleware.bind(pageService)); /* * System Init @@ -385,12 +381,7 @@ module.exports.startWebServer = async (dtp) => { if (process.env.HTTP_ENABLE === 'enabled') { if (process.env.HTTP_REDIRECT_SSL === 'enabled') { - module.log.info('creating HTTP SSL redirect app'); - module.redirectApp = express(); - module.redirectApp.use((req, res) => { - module.log.info('redirecting to SSL', { host: req.host, url: req.url }); - res.redirect(`https://${process.env.DTP_SITE_DOMAIN}${req.url}`); - }); + await module.createSslRedirectApp(dtp); await module.createHttpServer(dtp, module.redirectApp); } else { await module.createHttpServer(dtp, module.app); @@ -437,6 +428,19 @@ module.createHttpsServer = async (dtp, app) => { return module.https; }; +module.createSslRedirectApp = async (/* dtp */) => { + module.log.info('creating HTTP SSL redirect app'); + + module.redirectApp = express(); + + module.redirectApp.use((req, res) => { + module.log.info('redirecting to SSL', { host: req.host, url: req.url }); + res.redirect(`https://${process.env.DTP_SITE_DOMAIN}${req.url}`); + }); + + return module.redirectApp; +}; + module.startHttpServer = async (dtp, server, config) => { return new Promise((resolve, reject) => { module.log.info('starting HTTP server', { port: config.port, bind: config.address });