|
|
@ -18,12 +18,17 @@ class UserController extends SiteController {
|
|
|
|
async start ( ) {
|
|
|
|
async start ( ) {
|
|
|
|
const { dtp } = this;
|
|
|
|
const { dtp } = this;
|
|
|
|
const {
|
|
|
|
const {
|
|
|
|
|
|
|
|
csrfToken: csrfTokenService,
|
|
|
|
limiter: limiterService,
|
|
|
|
limiter: limiterService,
|
|
|
|
otpAuth: otpAuthService,
|
|
|
|
otpAuth: otpAuthService,
|
|
|
|
session: sessionService,
|
|
|
|
session: sessionService,
|
|
|
|
} = dtp.services;
|
|
|
|
} = dtp.services;
|
|
|
|
|
|
|
|
|
|
|
|
const upload = this.createMulter();
|
|
|
|
const upload = this.createMulter('user', {
|
|
|
|
|
|
|
|
limits: {
|
|
|
|
|
|
|
|
fileSize: 1024 * 1000 * 5, // 5MB
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const router = express.Router();
|
|
|
|
const router = express.Router();
|
|
|
|
dtp.app.use('/user', router);
|
|
|
|
dtp.app.use('/user', router);
|
|
|
@ -60,8 +65,10 @@ class UserController extends SiteController {
|
|
|
|
return next();
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
router.param('username', this.populateUsername.bind(this));
|
|
|
|
router.param('localUsername', this.populateLocalUsername.bind(this));
|
|
|
|
router.param('userId', this.populateUserId.bind(this));
|
|
|
|
router.param('coreUsername', this.populateCoreUsername.bind(this));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
router.param('localUserId', this.populateLocalUserId.bind(this));
|
|
|
|
router.param('coreUserId', this.populateCoreUserId.bind(this));
|
|
|
|
router.param('coreUserId', this.populateCoreUserId.bind(this));
|
|
|
|
|
|
|
|
|
|
|
|
router.post(
|
|
|
|
router.post(
|
|
|
@ -73,7 +80,7 @@ class UserController extends SiteController {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
router.post(
|
|
|
|
router.post(
|
|
|
|
'/:userId/profile-photo',
|
|
|
|
'/:localUserId/profile-photo',
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.postProfilePhoto),
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.postProfilePhoto),
|
|
|
|
checkProfileOwner,
|
|
|
|
checkProfileOwner,
|
|
|
|
upload.single('imageFile'),
|
|
|
|
upload.single('imageFile'),
|
|
|
@ -81,7 +88,7 @@ class UserController extends SiteController {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
router.post(
|
|
|
|
router.post(
|
|
|
|
'/:userId/settings',
|
|
|
|
'/:localUserId/settings',
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.postUpdateSettings),
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.postUpdateSettings),
|
|
|
|
checkProfileOwner,
|
|
|
|
checkProfileOwner,
|
|
|
|
upload.none(),
|
|
|
|
upload.none(),
|
|
|
@ -91,6 +98,7 @@ class UserController extends SiteController {
|
|
|
|
router.post(
|
|
|
|
router.post(
|
|
|
|
'/',
|
|
|
|
'/',
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.postCreate),
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.postCreate),
|
|
|
|
|
|
|
|
csrfTokenService.middleware({ name: 'user-create' }),
|
|
|
|
this.postCreateUser.bind(this),
|
|
|
|
this.postCreateUser.bind(this),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
@ -124,7 +132,7 @@ class UserController extends SiteController {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
router.get(
|
|
|
|
router.get(
|
|
|
|
'/:userId/settings',
|
|
|
|
'/:localUsername/settings',
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.getSettings),
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.getSettings),
|
|
|
|
authRequired,
|
|
|
|
authRequired,
|
|
|
|
otpMiddleware,
|
|
|
|
otpMiddleware,
|
|
|
@ -132,7 +140,7 @@ class UserController extends SiteController {
|
|
|
|
this.getUserSettingsView.bind(this),
|
|
|
|
this.getUserSettingsView.bind(this),
|
|
|
|
);
|
|
|
|
);
|
|
|
|
router.get(
|
|
|
|
router.get(
|
|
|
|
'/:username',
|
|
|
|
'/:localUsername',
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.getUserProfile),
|
|
|
|
limiterService.createMiddleware(limiterService.config.user.getUserProfile),
|
|
|
|
authRequired,
|
|
|
|
authRequired,
|
|
|
|
otpMiddleware,
|
|
|
|
otpMiddleware,
|
|
|
@ -148,54 +156,127 @@ class UserController extends SiteController {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async populateUsername (req, res, next, username) {
|
|
|
|
async populateCoreUsername (req, res, next, coreUsername) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
res.locals.userProfile = await userService.getPublicProfile('User', username);
|
|
|
|
res.locals.username = userService.filterUsername(coreUsername);
|
|
|
|
if (!res.locals.userProfile) {
|
|
|
|
res.locals.userProfileId = await userService.getCoreUserId(res.locals.username);
|
|
|
|
throw new SiteError(404, 'Member not found');
|
|
|
|
if (!res.locals.userProfileId) {
|
|
|
|
|
|
|
|
throw new SiteError(404, 'Core member not found');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return next();
|
|
|
|
// manually chain over to the ID parameter resolver
|
|
|
|
|
|
|
|
return this.populateCoreUserId(req, res, next, res.locals.userProfileId);
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to populate username with public profile', { username, error });
|
|
|
|
this.log.error('failed to populate core username', { coreUsername, error });
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'populateCoreUsername',
|
|
|
|
|
|
|
|
message: `failed to populate Core user: ${error.message}`,
|
|
|
|
|
|
|
|
data: { coreUsername, error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return next(error);
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async populateUserId (req, res, next, userId) {
|
|
|
|
async populateCoreUserId (req, res, next, coreUserId) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
userId = mongoose.Types.ObjectId(userId);
|
|
|
|
res.locals.userProfileId = mongoose.Types.ObjectId(coreUserId);
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
return next(new SiteError(406, 'Invalid User'));
|
|
|
|
if (req.user && (req.user.type === 'CoreUser') && req.user._id.equals(res.locals.userProfileId)) {
|
|
|
|
|
|
|
|
res.locals.userProfile = await userService.getCoreUserAccount(res.locals.userProfileId);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
res.locals.userProfile = await userService.getCoreUserProfile(res.locals.userProfileId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
|
|
|
|
res.locals.userProfile = await userService.getUserAccount(userId);
|
|
|
|
if (!res.locals.userProfile) {
|
|
|
|
|
|
|
|
throw new SiteError(404, 'Core member not found');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return next();
|
|
|
|
return next();
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to populate userId', { userId, error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'populateCoreUserId',
|
|
|
|
|
|
|
|
message: `failed to populate core user: ${error.message}`,
|
|
|
|
|
|
|
|
data: { coreUserId, error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return next(error);
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async populateCoreUserId (req, res, next, coreUserId) {
|
|
|
|
async populateLocalUsername (req, res, next, username) {
|
|
|
|
const { coreNode: coreNodeService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
coreUserId = mongoose.Types.ObjectId(coreUserId);
|
|
|
|
res.locals.username = userService.filterUsername(username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res.locals.userProfileId = await userService.getLocalUserId(res.locals.username);
|
|
|
|
|
|
|
|
if (!res.locals.userProfileId) {
|
|
|
|
|
|
|
|
throw new SiteError(404, 'Local member not found');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (req.user && (req.user.type === 'User') && req.user._id.equals(res.locals.userProfileId)) {
|
|
|
|
|
|
|
|
res.locals.userProfile = await userService.getLocalUserAccount(res.locals.userProfileId);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
res.locals.userProfile = await userService.getLocalUserProfile(res.locals.userProfileId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return next();
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
return next(new SiteError(406, 'Invalid User'));
|
|
|
|
this.log.error('failed to populate local username', { username, error });
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'populateLocalUsername',
|
|
|
|
|
|
|
|
message: `failed to populate local user: ${error.message}`,
|
|
|
|
|
|
|
|
data: { username, error },
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async populateLocalUserId (req, res, next, userId) {
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
res.locals.userProfile = await coreNodeService.getUserByLocalId(coreUserId);
|
|
|
|
res.locals.userProfileId = mongoose.Types.ObjectId(userId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (req.user && (req.user.type === 'User') && req.user._id.equals(res.locals.userProfileId)) {
|
|
|
|
|
|
|
|
res.locals.userProfile = await userService.getLocalUserAccount(res.locals.userProfileId);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
res.locals.userProfile = await userService.getLocalUserProfile(res.locals.userProfileId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!res.locals.userProfile) {
|
|
|
|
|
|
|
|
throw new SiteError(404, 'Local member not found');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return next();
|
|
|
|
return next();
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to populate coreUserId', { coreUserId, error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'populateLocalUserId',
|
|
|
|
|
|
|
|
message: `failed to populate local user: ${error.message}`,
|
|
|
|
|
|
|
|
data: { userId, error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return next(error);
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async postCreateUser (req, res, next) {
|
|
|
|
async postCreateUser (req, res, next) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// verify that the request has submitted a captcha
|
|
|
|
// verify that the request has submitted a captcha
|
|
|
|
if ((typeof req.body.captcha !== 'string') || req.body.captcha.length === 0) {
|
|
|
|
if ((typeof req.body.captcha !== 'string') || req.body.captcha.length === 0) {
|
|
|
@ -213,11 +294,42 @@ class UserController extends SiteController {
|
|
|
|
// create the user account
|
|
|
|
// create the user account
|
|
|
|
res.locals.user = await userService.create(req.body);
|
|
|
|
res.locals.user = await userService.create(req.body);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const form = Object.assign(req.body);
|
|
|
|
|
|
|
|
if (form.password) {
|
|
|
|
|
|
|
|
delete form.password;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (form.passwordv) {
|
|
|
|
|
|
|
|
delete form.passwordv;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'postCreateUser',
|
|
|
|
|
|
|
|
data: {
|
|
|
|
|
|
|
|
form,
|
|
|
|
|
|
|
|
user: {
|
|
|
|
|
|
|
|
_id: res.locals.user._id,
|
|
|
|
|
|
|
|
username: res.locals.user.username,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// log the user in
|
|
|
|
// log the user in
|
|
|
|
req.login(res.locals.user, (error) => {
|
|
|
|
req.login(res.locals.user, (error) => {
|
|
|
|
if (error) {
|
|
|
|
if (error) {
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'postCreateUser',
|
|
|
|
|
|
|
|
message: `failed to start user session: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return next(error);
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'postCreateUser',
|
|
|
|
|
|
|
|
message: 'user session started',
|
|
|
|
|
|
|
|
});
|
|
|
|
res.redirect(`/user/${res.locals.user.username}`);
|
|
|
|
res.redirect(`/user/${res.locals.user.username}`);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
@ -227,19 +339,35 @@ class UserController extends SiteController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async postProfilePhoto (req, res) {
|
|
|
|
async postProfilePhoto (req, res) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const displayList = this.createDisplayList('profile-photo');
|
|
|
|
|
|
|
|
await userService.updatePhoto(req.user, req.file);
|
|
|
|
await userService.updatePhoto(req.user, req.file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const displayList = this.createDisplayList('profile-photo');
|
|
|
|
displayList.showNotification(
|
|
|
|
displayList.showNotification(
|
|
|
|
'Profile photo updated successfully.',
|
|
|
|
'Profile photo updated successfully.',
|
|
|
|
'success',
|
|
|
|
'success',
|
|
|
|
'bottom-center',
|
|
|
|
'bottom-center',
|
|
|
|
2000,
|
|
|
|
2000,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'postProfilePhoto',
|
|
|
|
|
|
|
|
message: 'profile photo updated',
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to update profile photo', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'postProfilePhoto',
|
|
|
|
|
|
|
|
message: `failed to update profile photo: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
success: false,
|
|
|
|
success: false,
|
|
|
|
message: error.message,
|
|
|
|
message: error.message,
|
|
|
@ -248,19 +376,35 @@ class UserController extends SiteController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async postHeaderImage (req, res) {
|
|
|
|
async postHeaderImage (req, res) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const displayList = this.createDisplayList('header-image');
|
|
|
|
|
|
|
|
await userService.updateHeaderImage(req.user, req.file);
|
|
|
|
await userService.updateHeaderImage(req.user, req.file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const displayList = this.createDisplayList('header-image');
|
|
|
|
displayList.showNotification(
|
|
|
|
displayList.showNotification(
|
|
|
|
'Header image updated successfully.',
|
|
|
|
'Header image updated successfully.',
|
|
|
|
'success',
|
|
|
|
'success',
|
|
|
|
'bottom-center',
|
|
|
|
'bottom-center',
|
|
|
|
2000,
|
|
|
|
2000,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'postHeaderImage',
|
|
|
|
|
|
|
|
message: 'header image updated',
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to update header image', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'postHeaderImage',
|
|
|
|
|
|
|
|
message: `failed to update header image: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
success: false,
|
|
|
|
success: false,
|
|
|
|
message: error.message,
|
|
|
|
message: error.message,
|
|
|
@ -269,16 +413,30 @@ class UserController extends SiteController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async postUpdateCoreSettings (req, res) {
|
|
|
|
async postUpdateCoreSettings (req, res) {
|
|
|
|
const { coreNode: coreNodeService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
coreNode: coreNodeService,
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const displayList = this.createDisplayList('app-settings');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await coreNodeService.updateUserSettings(req.user, req.body);
|
|
|
|
await coreNodeService.updateUserSettings(req.user, req.body);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const displayList = this.createDisplayList('app-settings');
|
|
|
|
displayList.reload();
|
|
|
|
displayList.reload();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'postUpdateCoreSettings',
|
|
|
|
|
|
|
|
message: 'CoreUser settings updated',
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to update CoreUser settings', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'postUpdateCoreSettings',
|
|
|
|
|
|
|
|
message: `failed to update CoreUser settings: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
success: false,
|
|
|
|
success: false,
|
|
|
|
message: error.message,
|
|
|
|
message: error.message,
|
|
|
@ -287,16 +445,30 @@ class UserController extends SiteController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async postUpdateSettings (req, res) {
|
|
|
|
async postUpdateSettings (req, res) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
await userService.updateSettings(req.user, req.body);
|
|
|
|
await userService.updateSettings(req.user, req.body);
|
|
|
|
|
|
|
|
|
|
|
|
const displayList = this.createDisplayList('app-settings');
|
|
|
|
const displayList = this.createDisplayList('app-settings');
|
|
|
|
displayList.reload();
|
|
|
|
displayList.reload();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'postUpdateSettings',
|
|
|
|
|
|
|
|
message: 'account settings updates',
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to update account settings', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'postUpdateSettings',
|
|
|
|
|
|
|
|
message: `failed to update account settings: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
success: false,
|
|
|
|
success: false,
|
|
|
|
message: error.message,
|
|
|
|
message: error.message,
|
|
|
@ -309,13 +481,26 @@ class UserController extends SiteController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getOtpDisable (req, res) {
|
|
|
|
async getOtpDisable (req, res) {
|
|
|
|
const { otpAuth: otpAuthService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
otpAuth: otpAuthService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
await otpAuthService.destroyOtpSession(req, 'Account');
|
|
|
|
await otpAuthService.destroyOtpSession(req, 'Account');
|
|
|
|
await otpAuthService.removeForUser(req.user, 'Account');
|
|
|
|
await otpAuthService.removeForUser(req.user, 'Account');
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'getOtpDisable',
|
|
|
|
|
|
|
|
message: 'one-time passwords disabled',
|
|
|
|
|
|
|
|
});
|
|
|
|
res.render('user/otp-disabled');
|
|
|
|
res.render('user/otp-disabled');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to disable OTP service for Account', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'getOtpDisable',
|
|
|
|
|
|
|
|
message: `failed to disable OTP: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
res.status(error.statusCode || 500).json({
|
|
|
|
res.status(error.statusCode || 500).json({
|
|
|
|
success: false,
|
|
|
|
success: false,
|
|
|
|
message: error.message,
|
|
|
|
message: error.message,
|
|
|
@ -324,44 +509,71 @@ class UserController extends SiteController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getCoreUserSettingsView (req, res, next) {
|
|
|
|
async getCoreUserSettingsView (req, res, next) {
|
|
|
|
const { otpAuth: otpAuthService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
otpAuth: otpAuthService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
res.locals.hasOtpAccount = await otpAuthService.isUserProtected(req.user, 'Account');
|
|
|
|
res.locals.hasOtpAccount = await otpAuthService.isUserProtected(req.user, 'Account');
|
|
|
|
res.locals.startTab = req.query.st || 'watch';
|
|
|
|
res.locals.startTab = req.query.st || 'watch';
|
|
|
|
res.render('user/settings-core');
|
|
|
|
res.render('user/settings-core');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to render CoreUser settings view', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'getCoreUserSettingsView',
|
|
|
|
|
|
|
|
message: `failed to render the view: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return next(error);
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getUserSettingsView (req, res, next) {
|
|
|
|
async getUserSettingsView (req, res, next) {
|
|
|
|
const { otpAuth: otpAuthService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
otpAuth: otpAuthService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
res.locals.hasOtpAccount = await otpAuthService.isUserProtected(req.user, 'Account');
|
|
|
|
res.locals.hasOtpAccount = await otpAuthService.isUserProtected(req.user, 'Account');
|
|
|
|
res.locals.startTab = req.query.st || 'watch';
|
|
|
|
res.locals.startTab = req.query.st || 'watch';
|
|
|
|
res.render('user/settings');
|
|
|
|
res.render('user/settings');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to render user settings view', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'getUserSettingsView',
|
|
|
|
|
|
|
|
message: `failed to render the view: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return next(error);
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getUserView (req, res, next) {
|
|
|
|
async getUserView (req, res, next) {
|
|
|
|
const { comment: commentService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
comment: commentService,
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
res.locals.pageTitle = `${res.locals.userProfile.username}'s Profile`;
|
|
|
|
res.locals.pageTitle = `${res.locals.userProfile.username}'s Profile`;
|
|
|
|
res.locals.pagination = this.getPaginationParameters(req, 20);
|
|
|
|
res.locals.pagination = this.getPaginationParameters(req, 20);
|
|
|
|
res.locals.commentHistory = await commentService.getForAuthor(req.user, res.locals.pagination);
|
|
|
|
res.locals.commentHistory = await commentService.getForAuthor(req.user, res.locals.pagination);
|
|
|
|
res.render('user/profile');
|
|
|
|
res.render('user/profile');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to produce user profile view', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'getUserView',
|
|
|
|
|
|
|
|
message: `failed to render the view: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return next(error);
|
|
|
|
return next(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async deleteProfilePhoto (req, res) {
|
|
|
|
async deleteProfilePhoto (req, res) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const displayList = this.createDisplayList('app-settings');
|
|
|
|
const displayList = this.createDisplayList('app-settings');
|
|
|
|
await userService.removePhoto(req.user);
|
|
|
|
await userService.removePhoto(req.user);
|
|
|
@ -371,9 +583,19 @@ class UserController extends SiteController {
|
|
|
|
'bottom-center',
|
|
|
|
'bottom-center',
|
|
|
|
2000,
|
|
|
|
2000,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'deleteProfilePhoto',
|
|
|
|
|
|
|
|
message: 'profile photo removed',
|
|
|
|
|
|
|
|
});
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to remove profile photo', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'deleteProfilePhoto',
|
|
|
|
|
|
|
|
message: `failed to remove profile photo: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
success: false,
|
|
|
|
success: false,
|
|
|
|
message: error.message,
|
|
|
|
message: error.message,
|
|
|
@ -382,7 +604,10 @@ class UserController extends SiteController {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async deleteHeaderImage (req, res) {
|
|
|
|
async deleteHeaderImage (req, res) {
|
|
|
|
const { user: userService } = this.dtp.services;
|
|
|
|
const {
|
|
|
|
|
|
|
|
logan: loganService,
|
|
|
|
|
|
|
|
user: userService,
|
|
|
|
|
|
|
|
} = this.dtp.services;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
const displayList = this.createDisplayList('remove-header-image');
|
|
|
|
const displayList = this.createDisplayList('remove-header-image');
|
|
|
|
await userService.removeHeaderImage(req.user);
|
|
|
|
await userService.removeHeaderImage(req.user);
|
|
|
@ -392,9 +617,19 @@ class UserController extends SiteController {
|
|
|
|
'bottom-center',
|
|
|
|
'bottom-center',
|
|
|
|
2000,
|
|
|
|
2000,
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'info',
|
|
|
|
|
|
|
|
event: 'deleteHeaderImage',
|
|
|
|
|
|
|
|
message: 'profile header image removed',
|
|
|
|
|
|
|
|
});
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
res.status(200).json({ success: true, displayList });
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
this.log.error('failed to remove header image', { error });
|
|
|
|
loganService.sendRequestEvent(module.exports, req, {
|
|
|
|
|
|
|
|
level: 'error',
|
|
|
|
|
|
|
|
event: 'deleteHeaderImage',
|
|
|
|
|
|
|
|
message: `failed to remove header image: ${error.message}`,
|
|
|
|
|
|
|
|
data: { error },
|
|
|
|
|
|
|
|
});
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
return res.status(error.statusCode || 500).json({
|
|
|
|
success: false,
|
|
|
|
success: false,
|
|
|
|
message: error.message,
|
|
|
|
message: error.message,
|
|
|
@ -406,5 +641,6 @@ class UserController extends SiteController {
|
|
|
|
module.exports = {
|
|
|
|
module.exports = {
|
|
|
|
slug: 'user',
|
|
|
|
slug: 'user',
|
|
|
|
name: 'user',
|
|
|
|
name: 'user',
|
|
|
|
|
|
|
|
className: 'UserController',
|
|
|
|
create: async (dtp) => { return new UserController(dtp); },
|
|
|
|
create: async (dtp) => { return new UserController(dtp); },
|
|
|
|
};
|
|
|
|
};
|
|
|
|