diff --git a/.firebase/hosting.ZGlzdA.cache b/.firebase/hosting.ZGlzdA.cache new file mode 100644 index 0000000..a25b6bd --- /dev/null +++ b/.firebase/hosting.ZGlzdA.cache @@ -0,0 +1,10 @@ +index.html,1605445365695,31e756df6cc5f4a8c0929159b7138da8a9e83bf048a8cb8f12e8260410721e49 +icon-180.png,1605445365697,92b3a619d6458a45d8a0c0fe1cc30d00d2b8667f7c7779a1ee4047743ad878c4 +manifest.json,1605445365697,f9f961e572d8185f8193c231ce9387026d500a021e88cabce702f4a4b5ddca62 +style.css,1605445365695,585b07896f1e83b449fc299fe3768854d25e0159ef7d1cc79029d012f234d2e9 +sw.js,1605445365695,256cd2d7ba9008c58800eb0f9b3d9a821feb3b2f65ca44528396427b4ea6548d +workbox-468c4d03.js,1605445365697,ea5fb6b5fef5cc7f273684fd2e59ac0cebd89aa17ee65eb3025aae71ad25caf5 +icon-192.png,1605445365700,019b6801c3ed961b26e089a9834c76036841020c6e1b32dad09b99011a46fd4f +favicon.ico,1605445365697,8bd2763f4080b268398c699ed305c33029429fb7c2f01f7fc8a2526a76e9beab +icon-512.png,1605445365695,5546a701cef8feed3551ec81d90e96227387f5b2f5c7170edf54a9f45c26273f +main.eaaaf6bc3fbc63029ff8.js,1605445365695,afa58da02ab17097146b0eaa731f3cdd2913895d0e259873fac5bdbf6533a902 diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 0000000..a3c51b2 --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "fb2ical-3051b" + } +} diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..15d17eb --- /dev/null +++ b/firebase.json @@ -0,0 +1,25 @@ +{ + "emulators": { + "functions": { + "port": 5001 + }, + "ui": { + "enabled": true, + "port": 5002 + } + }, + "hosting": { + "public": "dist/", + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ], + "rewrites": [ + { + "source": "/**", + "function": "app" + } + ] + } +} diff --git a/functions/index.js b/functions/index.js index 58c59a0..3b1c1ac 100644 --- a/functions/index.js +++ b/functions/index.js @@ -2,19 +2,19 @@ const functions = require('firebase-functions'); const admin = require('firebase-admin') const { configureApplication } = require('./lib/app') -const { createAppLogger } = require('../lib/log-utils') -const { - createRouteLogger, - createErrorLogger, -} = require('../lib/middlewares') +// const { createAppLogger } = require('./lib/log-utils') +// const { +// createRouteLogger, +// createErrorLogger, +// } = require('./lib/middlewares') admin.initializeApp() const isDevelopment = process.env.NODE_ENV === 'development' -const appLogger = createAppLogger({ dev: isDevelopment }) -const errorLogger = createErrorLogger({ dev: isDevelopment }) -const routeLogger = isDevelopment ? createRouteLogger({ dev: isDevelopment }) : null +// const appLogger = createAppLogger({ dev: isDevelopment }) +// const errorLogger = createErrorLogger({ dev: isDevelopment }) +// const routeLogger = isDevelopment ? createRouteLogger({ dev: isDevelopment }) : null const corsOptions = isDevelopment ? { origin: 'http://localhost:5000', } : null diff --git a/lib/app/index.js b/lib/app/index.js new file mode 100644 index 0000000..2789372 --- /dev/null +++ b/lib/app/index.js @@ -0,0 +1,106 @@ +const express = require('express') +const bodyParser = require('body-parser') +const path = require('path') +const favicon = require('serve-favicon') +const rateLimit = require('express-rate-limit') +const cors = require('cors') + +const { + error, + notFound, + download, + downloadHTML, +} = require('../routes') + +const { + genericErrorHandler, + checkURLParameter, + forceSecure, +} = require('../middlewares') + +const certEndpoint = process.env.CERT_ENDPOINT || '' +const certSecret = process.env.CERT_SECRET || '' +const enforceHTTPS = Boolean(process.env.ENFORCE_HTTPS) + +const configureApplication = ({ + appLogger, + errorLogger, + routeLogger, + corsOptions, + rateLimitEnabled, +}) => { + const pkg = require('../../package.json') + const version = pkg.version + + const app = express() + + if (corsOptions) { + app.use(cors(corsOptions)) + } + + // Force app to always redirect to HTTPS + // use when you can't configure web server + if (enforceHTTPS) { + app.use(forceSecure) + } + + if (appLogger) { + app.post('/download/html', downloadHTML(appLogger)) + app.post('/download', download(appLogger)) + } + + // Server logs You can alternatively enable these to mimic logs created + // by your web server + if (routeLogger) { + app.use(routeLogger) + } + + if (errorLogger) { + app.use(errorLogger) + } + + app.set('view engine', 'ejs') + app.set('views', path.join(__dirname, '..', 'views')) + app.set('trust proxy', 1) + + app.use(express.static(path.join(__dirname, '..', '..', 'dist'))) + // app.use(favicon(path.join(__dirname, '..', 'dist', 'favicon.ico'))) + app.use(bodyParser.urlencoded({ extended: true })) + + if (rateLimitEnabled) { + const limiter = rateLimit({ + windowMs: 60 * 1000, + max: 10, + }) + + app.use('/download/html', limiter) + app.use('/download', limiter) + } + + if (certEndpoint) { + app.get(`/${certEndpoint}`, (req, res) => { + res.status(200).send(certSecret) + }) + } + + app.get('/error', error) + + app.get('/about', (req, res) => { + res.render('about', { version }) + }) + + // NOTE: Capture all unkown URLs + app.get('*', notFound) + + app.use('/download/html', checkURLParameter) + + app.use('/download', checkURLParameter) + + app.use(genericErrorHandler) + + return app +} + +module.exports = { + configureApplication, +} diff --git a/lib/index.js b/lib/index.js index 0f9c776..5f50d75 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,87 +1,22 @@ -const express = require('express') -const bodyParser = require('body-parser') -const path = require('path') -const favicon = require('serve-favicon') -const rateLimit = require('express-rate-limit') - +const { configureApplication } = require('./app') +const { createAppLogger } = require('./log-utils') const { - error, - notFound, - download, - downloadHTML, -} = require('./routes') - -const { - genericErrorHandler, - checkURLParameter, - forceSecure, createRouteLogger, createErrorLogger, } = require('./middlewares') -const { createAppLogger } = require('./log-utils') -const port = process.env.PORT -const certEndpoint = process.env.CERT_ENDPOINT || '' -const certSecret = process.env.CERT_SECRET || '' const isDevelopment = process.env.NODE_ENV === 'development' -const enforceHTTPS = Boolean(process.env.ENFORCE_HTTPS) +const port = process.env.PORT -const app = express() const appLogger = createAppLogger({ dev: isDevelopment }) -const limiter = rateLimit({ - windowMs: 60 * 1000, - max: 10, +const errorLogger = createErrorLogger({ dev: isDevelopment }) +const routeLogger = isDevelopment ? createRouteLogger({ dev: isDevelopment }) : null + +const app = configureApplication({ + appLogger, + errorLogger, + routeLogger, + rateLimitEnabled: true }) -const pkg = require('../package.json') -const version = pkg.version || '' - -// Force app to always redirect to HTTPS -// use when you can't configure web server -if (enforceHTTPS) { - app.use(forceSecure) -} - -// Server logs -// You can alternatively enable these to mimic logs created -// by your web server -if (isDevelopment) { - app.use(createRouteLogger({ dev: isDevelopment })) -} - -app.set('view engine', 'ejs') -app.set('views', path.join(__dirname, 'views')) -app.set('trust proxy', 1) - -app.use(express.static(path.join(__dirname, '..', 'dist'))) -//app.use(favicon(path.join(__dirname, '..', 'dist', 'favicon.ico'))) -app.use(bodyParser.urlencoded({ extended: true })) - -const indexFile = path.join(__dirname, '..', 'dist', 'index.html') - -if (certEndpoint) { - app.get(`/${certEndpoint}`, (req, res) => { - res.status(200).send(certSecret) - }) -} - -app.get('/error', error) - -app.get('/about', (req, res) => { - res.render('about', { version }) -}) - -// NOTE: Capture all unkown URLs -app.get('*', notFound) - -app.use('/download/html', limiter) -app.use('/download/html', checkURLParameter) -app.post('/download/html', downloadHTML(appLogger)) - -app.use('/download', limiter) -app.use('/download', checkURLParameter) -app.post('/download', download) - -app.use(createErrorLogger({ dev: isDevelopment })) -app.use(genericErrorHandler) app.listen(port) diff --git a/lib/routes/download.js b/lib/routes/download.js index 3733bec..0e04ec8 100644 --- a/lib/routes/download.js +++ b/lib/routes/download.js @@ -18,12 +18,12 @@ const downloadHTML = (logger) => (async (req, res, next) => { } }) -const download = async (req, res, next) => { +const download = (logger) => (async (req, res, next) => { try { const { url } = req.body const ics = await retrieveICS(url, { - logger: appLogger, + logger, crawl, }) @@ -34,7 +34,7 @@ const download = async (req, res, next) => { } catch (err) { next(err) } -} +}) module.exports = { downloadHTML, diff --git a/lib/services/crawler.js b/lib/services/crawler.js index 30b8156..681ff96 100644 --- a/lib/services/crawler.js +++ b/lib/services/crawler.js @@ -28,3 +28,4 @@ const crawl = async (url, { logger }) => { } module.exports = crawl + diff --git a/lib/static/404.html b/lib/static/404.html new file mode 100644 index 0000000..829eda8 --- /dev/null +++ b/lib/static/404.html @@ -0,0 +1,33 @@ + + +
+ + +The specified file was not found on this website. Please check the URL for mistakes and try again.
+This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html
file in your project's configured public
directory.