Browse Source

user management features

pull/1/head
Rob Colbert 3 years ago
parent
commit
21f63ba446
  1. 2
      app/controllers/admin/user.js
  2. 16
      app/controllers/user.js
  3. 5
      app/models/user.js
  4. 3
      app/services/link.js
  5. 15
      app/services/user.js
  6. 7
      app/views/admin/user/form.pug
  7. 8
      app/views/admin/user/index.pug
  8. 15
      data/patches/user-permissions.js

2
app/controllers/admin/user.js

@ -61,7 +61,7 @@ class UserController extends SiteController {
const { user: userService } = this.dtp.services;
try {
res.locals.pagination = this.getPaginationParameters(req, 10);
res.locals.userAccounts = await userService.getUserAccounts(res.locals.pagination);
res.locals.userAccounts = await userService.getUserAccounts(res.locals.pagination, req.query.u);
res.render('admin/user/index');
} catch (error) {
return next(error);

16
app/controllers/user.js

@ -107,7 +107,23 @@ class UserController extends SiteController {
async postCreateUser (req, res, next) {
const { user: userService } = this.dtp.services;
try {
// verify that the request has submitted a captcha
if ((typeof req.body.captcha !== 'string') || req.body.captcha.length === 0) {
throw new SiteError(403, 'Invalid signup attempt');
}
// verify that the session has a signup captcha
if (!req.session.captcha || !req.session.captcha.signup) {
throw new SiteError(403, 'Invalid signup attempt');
}
// verify that the captcha from the form matches the captcha in the signup session flow
if (req.body.captcha !== req.session.captcha.signup) {
throw new SiteError(403, 'The captcha value is not correct');
}
// create the user account
res.locals.user = await userService.create(req.body);
// log the user in
req.login(res.locals.user, (error) => {
if (error) {
return next(error);

5
app/models/user.js

@ -16,6 +16,7 @@ const UserFlagsSchema = new Schema({
const UserPermissionsSchema = new Schema({
canLogin: { type: Boolean, default: true, required: true },
canChat: { type: Boolean, default: true, required: true },
canCreateLinks: { type: Boolean, default: true, required: true },
});
const UserSchema = new Schema({
@ -33,6 +34,10 @@ const UserSchema = new Schema({
},
flags: { type: UserFlagsSchema, select: false },
permissions: { type: UserPermissionsSchema, select: false },
stats: {
profileViewCountTotal: { type: Number, default: 0, required: true },
profileViewCountUnique: { type: Number, default: 0, required: true },
}
});
module.exports = mongoose.model('User', UserSchema);

3
app/services/link.js

@ -44,6 +44,9 @@ class LinkService extends SiteService {
}
async create (user, linkDefinition) {
if (!user.permissions.canCreateLinks) {
throw new SiteError(403, 'You are prohibited from creating links');
}
this.validateUrl(linkDefinition.href);
const NOW = new Date();

15
app/services/user.js

@ -88,6 +88,7 @@ class UserService {
user.permissions = {
canLogin: true,
canChat: true,
canCreateLinks: true,
};
this.log.info('creating new user account', { email: userDefinition.email });
@ -121,6 +122,7 @@ class UserService {
'flags.isModerator': userDefinition.isModerator === 'on',
'permissions.canLogin': userDefinition.canLogin === 'on',
'permissions.canChat': userDefinition.canChat === 'on',
'permissions.canCreateLinks': userDefinition.canCreateLinks === 'on',
},
},
);
@ -268,9 +270,13 @@ class UserService {
return user;
}
async getUserAccounts (pagination) {
async getUserAccounts (pagination, username) {
let search = { };
if (username) {
search.username_lc = { $regex: `^${username.toLowerCase().trim()}` };
}
const users = await User
.find()
.find(search)
.sort({ username_lc: 1 })
.select('+email +flags +permissions')
.skip(pagination.skip)
@ -426,6 +432,11 @@ class UserService {
throw new SiteError(403, 'That username is reserved for system use');
}
}
async recordProfileView (user, req) {
const { resource: resourceService } = this.dtp.services;
await resourceService.recordView(req, 'User', user._id);
}
}
module.exports = {

7
app/views/admin/user/form.pug

@ -8,6 +8,10 @@ block content
form(method="POST", action=`/admin/user/${userAccount._id}`).uk-form
input(type="hidden", name="username", value= userAccount.username)
input(type="hidden", name="displayName", value= userAccount.displayName)
.uk-margin
label(for="bio").uk-form-label Bio
textarea(id="bio", name="bio", rows="4", placeholder= "Enter profile bio").uk-textarea.uk-resize-vertical= userAccount.bio
.uk-margin
div(uk-grid)
div(class="uk-width-1-1 uk-width-1-2@m")
@ -33,5 +37,8 @@ block content
label
input(id="can-chat", name="canChat", type="checkbox", checked= userAccount.permissions.canChat)
| Can Chat
label
input(id="can-create-links", name="canCreateLinks", type="checkbox", checked= userAccount.permissions.canCreateLinks)
| Can Create Links
button(type="submit").uk-button.uk-button-primary Update User

8
app/views/admin/user/index.pug

@ -1,6 +1,14 @@
extends ../layouts/main
block content
.uk-margin
form(method="GET", action="/admin/user").uk-form
div(uk-grid).uk-grid-collapse
.uk-width-expand
input(id="username", name="u", placeholder="Enter username", value= query && query.u ? query.u : undefined).uk-input
.uk-width-auto
button(type="submit").uk-button.uk-button-secondary.uk-light Search
.uk-overflow-auto
table.uk-table.uk-table-divider.uk-table-hover.uk-table-small.uk-table-justify
thead

15
data/patches/user-permissions.js

@ -0,0 +1,15 @@
'use strict';
/* globals db */
const cursor = db.users.find({ });
while (cursor.hasNext()) {
const user = cursor.next();
print(`updating user: ${user.username}`);
db.users.updateOne(
{ _id: user._id },
{
$set: { 'permissions.canCreateLinks': true },
},
);
}
Loading…
Cancel
Save