diff --git a/layouts/pages/index.ejs b/layouts/pages/index.ejs index a502eb88..6a22bd03 100644 --- a/layouts/pages/index.ejs +++ b/layouts/pages/index.ejs @@ -5,7 +5,9 @@ @@ -18,11 +20,11 @@ <%- include('partials/search', {style: 'homepage', focus: 'autofocus', msgOnFocus: template('search.placeholder')}) %> - <% if (locals.editLink) { %> -
- Edit - -
+ <% if (!locals.isPublic) { %> + <% if (locals.editLink) { %> +
+ Edit +
+ <% } %> <% } %> diff --git a/layouts/partials/userTools.ejs b/layouts/partials/userTools.ejs index 2bd5819b..1eedf482 100644 --- a/layouts/partials/userTools.ejs +++ b/layouts/partials/userTools.ejs @@ -1,19 +1,21 @@ -
-
- - - +<% if (!locals.isPublic) { %> + -
- - +
+ + -
-
+
+
+<% } %> diff --git a/server/routes/categories.js b/server/routes/categories.js index f714faaf..de9b9945 100644 --- a/server/routes/categories.js +++ b/server/routes/categories.js @@ -11,9 +11,12 @@ const {parseUrl} = require('../urlParser') router.get('*', handleCategory) module.exports = router +let isPublicUser = false + const categories = getTemplates('categories') async function handleCategory(req, res) { + isPublicUser = req.userInfo.userId === '0' log.info(`GET ${req.path}`) // FIXME: consider putting this in middleware and save on req const {meta, parent, data, root} = await parseUrl(req.path) @@ -40,6 +43,7 @@ async function handleCategory(req, res) { lastUpdatedBy: (meta.lastModifyingUser || {}).displayName, modifiedAt: meta.modifiedTime, createdAt: meta.createdTime, + isPublic: isPublicUser, editLink: meta.mimeType === 'text/html' ? meta.folder.webViewLink : meta.webViewLink, id, template: stringTemplate, @@ -108,6 +112,7 @@ function prepareContextualData(data, url, breadcrumb, parent, slug) { return { url: `/${arr.slice(0, i + 1).join('/')}`, name: cleanName(breadcrumbInfo[i].name), + isPublic: isPublicUser, editLink: breadcrumbInfo[i].webViewLink } }) @@ -130,6 +135,7 @@ function createRelatedList(slugs, self, baseUrl) { return { sort, name: prettyName, + isPublic: isPublicUser, editLink: webViewLink, resourceType, url, diff --git a/server/routes/pages.js b/server/routes/pages.js index 9acd77f2..229e5e06 100644 --- a/server/routes/pages.js +++ b/server/routes/pages.js @@ -63,6 +63,7 @@ async function handlePage(req, res) { if (page === 'categories' || page === 'index') { const tree = await getTree() const categories = buildDisplayCategories(tree) + res.format({ html: () => { res.render(template, {...categories, template: stringTemplate}) @@ -84,6 +85,7 @@ async function handlePage(req, res) { } res.render(template, {template: stringTemplate}) + res.render(template, {...categories, template: stringTemplate, isPublic: true}) } function buildDisplayCategories(tree) { diff --git a/server/routes/playlists.js b/server/routes/playlists.js index 48ae0218..042cd14d 100644 --- a/server/routes/playlists.js +++ b/server/routes/playlists.js @@ -11,7 +11,10 @@ const {parseUrl} = require('../urlParser') router.get('*', handlePlaylist) module.exports = router +let isPublicUser = false + async function handlePlaylist(req, res) { + isPublicUser = req.userInfo.userId === '0' const {meta, parent, data} = await parseUrl(req.path) if (!meta || !data) return 'next' @@ -66,6 +69,7 @@ function preparePlaylistOverview(playlistMeta, values, breadcrumb) { modifiedAt: playlistMeta.modifiedTime, lastUpdatedBy: (playlistMeta.lastModifyingUser || {}).displayName, createdAt: playlistMeta.createdTime, + isPublic: isPublicUser, editLink: playlistMeta.mimeType === 'text/html' ? playlistMeta.folder.webViewLink : playlistMeta.webViewLink }) @@ -97,6 +101,7 @@ async function preparePlaylistPage(data, url, parent) { return { url: `/${arr.slice(0, i + 1).join('/')}`, name: cleanName(breadcrumbInfo[i].name), + isPublic: isPublicUser, editLink: breadcrumbInfo[i].webViewLink } }) @@ -131,6 +136,7 @@ function prepareContextualData(playlistMeta, values, breadcrumb) { return { url: `/${arr.slice(0, i + 1).join('/')}`, name: cleanName(breadcrumbInfo[i].name), + isPublic: isPublicUser, editLink: breadcrumbInfo[i].webViewLink } }) @@ -141,6 +147,7 @@ function prepareContextualData(playlistMeta, values, breadcrumb) { sort: prettyName, name: prettyName, url: `${path}/${slug}`, + isPublic: isPublicUser, editLink: mimeType === 'text/html' ? folder.webViewLink : webViewLink, resourceType: resourceType } diff --git a/server/userAuth.js b/server/userAuth.js index cacd5a91..a99065a3 100644 --- a/server/userAuth.js +++ b/server/userAuth.js @@ -11,6 +11,7 @@ const {stringTemplate: template} = require('./utils') const router = require('express-promise-router')() const domains = new Set(process.env.APPROVED_DOMAINS.split(/,\s?/g)) +const isPublic = (process.env.TRUST_PROXY || '').toUpperCase() === 'TRUE' const authStrategies = ['google', 'Slack'] let authStrategy = process.env.OAUTH_STRATEGY @@ -84,7 +85,8 @@ router.get('/auth/redirect', passport.authenticate(authStrategy, {failureRedirec router.use((req, res, next) => { const isDev = process.env.NODE_ENV === 'development' const passportUser = (req.session.passport || {}).user || {} - if (isDev || (req.isAuthenticated() && isAuthorized(passportUser))) { + + if (isDev || isPublic || (req.isAuthenticated() && isAuthorized(passportUser))) { setUserInfo(req) return next() } @@ -111,15 +113,17 @@ function isAuthorized(user) { } function setUserInfo(req) { - if (process.env.NODE_ENV === 'development') { + if (process.env.NODE_ENV === 'development' || isPublic) { req.userInfo = { email: process.env.TEST_EMAIL || template('footer.defaultEmail'), - userId: '10', + userId: isPublic ? '0' : '10', analyticsUserId: md5('10library') } return } + const email = isSlackOauth ? req.session.passport.user.email : req.session.passport.user.emails[0].value + req.userInfo = req.userInfo ? req.userInfo : { userId: req.session.passport.user.id, analyticsUserId: md5(req.session.passport.user.id + 'library'), diff --git a/test/utils/bootstrap.js b/test/utils/bootstrap.js index bf780fb8..cc3fa1dc 100644 --- a/test/utils/bootstrap.js +++ b/test/utils/bootstrap.js @@ -13,6 +13,8 @@ process.env.GOOGLE_CLIENT_SECRET = 'abc123' process.env.SESSION_SECRET = 'abc123' process.env.APPROVED_DOMAINS = 'test.com, (.*)?ar.org, demo.user@demo.site.edu' process.env.GCP_PROJECT_ID = 'fake-project' +process.env.PUBLIC_SITE = true + const userInfo = { emails: [{value: 'test.user@test.com'}], email: 'test.user@test.com',