diff --git a/app/controllers/user.js b/app/controllers/user.js index a71ede5..37541bf 100644 --- a/app/controllers/user.js +++ b/app/controllers/user.js @@ -63,6 +63,7 @@ class UserController extends SiteController { } router.param('userId', this.populateUser.bind(this)); + router.param('coreUserId', this.populateCoreUser.bind(this)); router.post( '/:userId/profile-photo', @@ -86,6 +87,23 @@ class UserController extends SiteController { this.postCreateUser.bind(this), ); + router.get( + '/core/:coreUserId/settings', + limiterService.create(limiterService.config.user.getSettings), + authRequired, + otpMiddleware, + checkProfileOwner, + this.getUserSettingsView.bind(this), + ); + router.get( + '/core/:coreUserId', + limiterService.create(limiterService.config.user.getUserProfile), + authRequired, + otpMiddleware, + checkProfileOwner, + this.getUserView.bind(this), + ); + router.get( '/:userId/otp-setup', limiterService.create(limiterService.config.user.getOtpSetup), @@ -99,7 +117,6 @@ class UserController extends SiteController { this.getOtpDisable.bind(this), ); - router.get( '/:userId/settings', limiterService.create(limiterService.config.user.getSettings), @@ -145,6 +162,22 @@ class UserController extends SiteController { } } + async populateCoreUser (req, res, next, coreUserId) { + const { coreNode: coreNodeService } = this.dtp.services; + try { + coreUserId = mongoose.Types.ObjectId(coreUserId); + } catch (error) { + return next(new SiteError(406, 'Invalid User')); + } + try { + res.locals.userProfile = await coreNodeService.getUserByLocalId(coreUserId); + return next(); + } catch (error) { + this.log.error('failed to populate coreUserId', { coreUserId, error }); + return next(error); + } + } + async postCreateUser (req, res, next) { const { user: userService } = this.dtp.services; try { diff --git a/app/services/session.js b/app/services/session.js index a4be526..33aad3e 100644 --- a/app/services/session.js +++ b/app/services/session.js @@ -79,6 +79,13 @@ class SessionService extends SiteService { switch (serviceName) { case 'core': user = await coreNodeService.getUserByLocalId(userId); + delete user.core.oauth; + delete user.core.__v; + delete user.__v; + delete user.flags._id; + delete user.permissions._id; + delete user.stats._id; + delete user.optIn._id; break; case 'local': user = await userService.getUserAccount(userId); diff --git a/app/services/user.js b/app/services/user.js index d7e192e..2f741c3 100644 --- a/app/services/user.js +++ b/app/services/user.js @@ -13,7 +13,6 @@ const UserBlock = mongoose.model('UserBlock'); const passport = require('passport'); const PassportLocal = require('passport-local'); -const OAuth2Strategy = require('passport-oauth2'); const striptags = require('striptags'); const uuidv4 = require('uuid').v4; @@ -41,7 +40,6 @@ class UserService extends SiteService { this.log.info(`starting ${module.exports.name} service`); this.registerPassportLocal(); - this.registerPassportOAuth2(); if (process.env.DTP_ADMIN === 'enabled') { this.registerPassportAdmin(); @@ -305,8 +303,6 @@ class UserService extends SiteService { throw new SiteError(403, 'Admin privileges required'); } - this.log.debug('user authenticated', { user }); - return user; } @@ -332,25 +328,6 @@ class UserService extends SiteService { } } - registerPassportOAuth2 ( ) { - const AUTH_HOST = process.env.DTP_CORE_AUTH_HOST || 'localhost'; - const oauthOptions = { - authorizationURL: `http://${AUTH_HOST}/oauth2/authorize`, - tokenURL: `http://${AUTH_HOST}/oauth2/token`, - clientID: process.env.DTP_CORE_CLIENT_ID, - clientSecret: process.env.DTP_CORE_CLIENT_SECRET, - callbackURL: `http://${process.env.DTP_SITE_DOMAIN}/auth/core/callback`, - }; - passport.use(new OAuth2Strategy(oauthOptions, this.handleOAuth2Login.bind(this))); - } - - async handleOAuth2Login (accessToken, refreshToken, profile, cb) { - this.log.info('OAuth2 login', { accessToken, refreshToken, profile }); - User.findOrCreate({ exampleId: profile.id }, function (err, user) { - return cb(err, user); - }); - } - registerPassportAdmin ( ) { const options = { usernameField: 'username', diff --git a/app/views/components/navbar.pug b/app/views/components/navbar.pug index 17ac0ea..aa3255e 100644 --- a/app/views/components/navbar.pug +++ b/app/views/components/navbar.pug @@ -1,3 +1,5 @@ +include ../user/components/profile-icon + nav(uk-navbar).uk-navbar-container.uk-position-fixed.uk-position-top .uk-navbar-left .uk-navbar-item @@ -30,48 +32,19 @@ nav(uk-navbar).uk-navbar-container.uk-position-fixed.uk-position-top .uk-navbar-item if user div.no-select - if user.picture && user.picture.small - img( - src= `/image/${user.picture.small._id}`, - title="Member Menu", - ).site-profile-picture.sb-navbar - else - img( - src= "/img/default-member.png", - title="Member Menu", - ).site-profile-picture.sb-navbar + +renderProfileIcon(user, "Member Menu") div(uk-dropdown={ mode: 'click' }).uk-navbar-dropdown ul.uk-nav.uk-navbar-dropdown-nav li.uk-nav-heading.uk-text-center= user.displayName || user.username li.uk-nav-divider - if (user.channel) - li - a(href=`/channel/${user.channel.slug}`) - span.nav-item-icon - i.fas.fa-broadcast-tower - span(style="max-width: 120px;").uk-text-truncate= user.channel.name - if (user.channel.liveEpisode) - li - a(href=`/channel/${user.channel.slug}/broadcaster`) - span.nav-item-icon - i.fas.fa-box-open - span Broadcaster - li - a(href='/dashboard') - span.nav-item-icon - i.fas.fa-tachometer-alt - span Dashboard - - li.uk-nav-divider - li - a(href=`/user/${user._id}`) + a(href= user.core ? `/user/core/${user._id}` : `/user/${user._id}`) span.nav-item-icon i.fas.fa-user span Profile li - a(href=`/user/${user._id}/settings`) + a(href= user.core ? `/user/core/${user._id}/settings` : `/user/${user._id}/settings`) span.nav-item-icon i.fas.fa-cog span Settings diff --git a/app/views/index.pug b/app/views/index.pug index 0e4b3a3..07e9ee2 100644 --- a/app/views/index.pug +++ b/app/views/index.pug @@ -5,4 +5,6 @@ block content p img(src="/img/the-bobs.jpg", alt="The Bobs have questions").uk-width-large - p This application doesn't actually do anything. The Bobs would have questions. \ No newline at end of file + p This application doesn't actually do anything. The Bobs would have questions. + + pre= JSON.stringify(user, null, 2) \ No newline at end of file diff --git a/app/views/user/components/profile-icon.pug b/app/views/user/components/profile-icon.pug new file mode 100644 index 0000000..f2e05da --- /dev/null +++ b/app/views/user/components/profile-icon.pug @@ -0,0 +1,17 @@ +mixin renderProfileIcon (user, title) + if user.core + img( + src=`http://${user.core.meta.domain}/core/user/${user.coreUserId}/picture`, + title= title, + ).site-profile-picture.sb-navbar + else + if user.picture && user.picture.small + img( + src= `/image/${user.picture.small._id}`, + title= title, + ).site-profile-picture.sb-navbar + else + img( + src= "/img/default-member.png", + title= title, + ).site-profile-picture.sb-navbar diff --git a/lib/site-platform.js b/lib/site-platform.js index 4239460..f122b0f 100644 --- a/lib/site-platform.js +++ b/lib/site-platform.js @@ -101,7 +101,6 @@ module.connectRedis = async (dtp) => { module.redis = dtp.redis = new Redis(options); module.redis.setMaxListeners(64); // prevents warnings/errors with Bull Queue - await module.redis.connect(); module.ioEmitter = dtp.ioEmitter = ioEmitter(module.redis); module.log.info('Redis connected'); @@ -284,7 +283,7 @@ module.exports.startWebServer = async (dtp) => { const SESSION_DURATION = 1000 * 60 * 60 * 24 * 30; // 30 days module.sessionConfig = { - name: `session.${process.env.DTP_SITE_DOMAIN_KEY}.${process.env.NODE_ENV}`, + name: `dtp:${process.env.DTP_SITE_DOMAIN_KEY}.${process.env.NODE_ENV}`, secret: process.env.HTTP_SESSION_SECRET, resave: true, saveUninitialized: true,