Browse Source

user account management updates

develop
Rob Colbert 1 year ago
parent
commit
bdd7c8b1af
  1. 1
      .gitignore
  2. 35
      app/services/user.js
  3. 5
      app/views/admin/user/form.pug
  4. 13
      app/views/user/settings.pug
  5. 22
      dtp-libertylinks-cli.js
  6. 1
      package.json
  7. 4
      start-local
  8. 2
      start-production
  9. 4
      stop-production
  10. 5
      yarn.lock

1
.gitignore

@ -1,6 +1,7 @@
.env
data/minio
data/minio.old
node_modules
dist
data/minio

35
app/services/user.js

@ -186,6 +186,13 @@ class UserService {
},
},
);
if (userDefinition.password) {
if (userDefinition.password !== userDefinition.passwordVerify) {
throw new SiteError(400, 'The new password and password verification do not match.');
}
await this.updatePassword(user, userDefinition.password);
}
}
async authenticate (account, options) {
@ -309,6 +316,15 @@ class UserService {
return user;
}
async getByUsername (username) {
const user = await User
.findOne({ username_lc: username.trim().toLowerCase() })
.select('+email +flags +permissions')
.populate(this.populateUser)
.lean();
return user;
}
async getUserAccounts (pagination, username) {
let search = { };
if (username) {
@ -562,6 +578,25 @@ class UserService {
await User.updateOne({ _id: user._id }, { $unset: { 'header': '' } });
}
async updatePassword (user, password) {
const { crypto: cryptoService } = this.dtp.services;
const passwordSalt = uuidv4();
const passwordHash = cryptoService.maskPassword(passwordSalt, password);
this.log.info('updating user password', { userId: user._id });
await User.updateOne(
{ _id: user._id },
{
$set: {
passwordSalt: passwordSalt,
password: passwordHash,
}
}
);
}
async remove (user) {
const {
link: linkService,

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

@ -9,7 +9,10 @@ block content
.uk-card.uk-card-secondary.uk-card-small
.uk-card-header
.uk-text-large= userAccount.displayName || userAccount.email
div= userAccount.username
div(uk-grid).uk-grid-small.uk-grid-divided
.uk-width-auto= userAccount.username
.uk-width-auto
a(href=`mailto:${userAccount.email}`, uk-tooltip={ title: "Compose email" })= userAccount.email
.uk-card-body
.uk-margin

13
app/views/user/settings.pug

@ -52,5 +52,18 @@ block content
label(for="bio").uk-form-label Profile bio
textarea(id="bio", name="bio", rows="3", placeholder="Tell people about yourself").uk-textarea.uk-resize-vertival= user.bio
.uk-margin-medium
fieldset
legend Change Password
div(uk-grid)
div(class="uk-width-1-1 uk-width-1-2@s")
label(for="password").uk-form-label New password
input(id="password", name="password", type="password", placeholder="Enter new password").uk-input
.uk-text-small To change your password, enter it here.
div(class="uk-width-1-1 uk-width-1-2@s")
label(for="passwordv").uk-form-label Verify password
input(id="passwordv", name="passwordVerify", type="password", placeholder="Verify new password").uk-input
.uk-text-small Please verify the new password by entering it again.
.uk-margin
button(type="submit").uk-button.dtp-button-primary Update account settings

22
dtp-libertylinks-cli.js

@ -11,6 +11,7 @@ require('dotenv').config();
const path = require('path');
const mongoose = require('mongoose');
const generatePassword = require('password-generator');
const {
SitePlatform,
@ -112,6 +113,23 @@ module.resetIndexes = async ( ) => {
}
};
module.resetPassword = async (target) => {
const { user: userService } = module.services;
const User = mongoose.model('User');
try {
const user = await User.findOne({ email: target }).lean();
if (!user) {
throw new Error('user not found');
}
const password = generatePassword(8, true);
module.log.info('updating user password', { target, password });
await userService.updatePassword(user, password);
} catch (error) {
module.log.error('failed to reset user password', { target, error });
}
};
/*
* SERVER INIT
*/
@ -170,6 +188,10 @@ module.resetIndexes = async ( ) => {
await module.resetIndexes();
break;
case 'reset-password':
await module.resetPassword(target);
break;
default:
throw new Error(`invalid action: ${module.app.options.action}`);
}

1
package.json

@ -57,6 +57,7 @@
"otplib": "^12.0.1",
"passport": "^0.5.0",
"passport-local": "^1.0.0",
"password-generator": "^2.3.2",
"pug": "^3.0.2",
"qrcode": "^1.5.0",
"rate-limiter-flexible": "^2.3.6",

4
start-local

@ -5,7 +5,9 @@ MINIO_ROOT_PASSWORD="7db281be-0cd2-497e-b759-c74c3d35e274"
export MINIO_ROOT_USER MINIO_ROOT_PASSWORD
forever start --killSignal=SIGINT app/workers/host-services.js
forever start --killSignal=SIGINT app/workers/reeeper.js
minio server ./data/minio --console-address ":9001"
forever stop app/workers/host-services.js
forever stop app/workers/reeeper.js
forever stop app/workers/host-services.js

2
start-production

@ -3,8 +3,8 @@
#
# WORKERS
#
forever start --killSignal=SIGINT app/workers/reeeper.js
forever start --killSignal=SIGINT app/workers/host-services.js
forever start --killSignal=SIGINT app/workers/reeeper.js
#
# APP HOSTS

4
stop-production

@ -8,5 +8,5 @@ forever stop dtp-libertylinks.js
#
# WORKERS
#
forever stop app/workers/host-services.js
forever stop app/workers/reeeper.js
forever stop app/workers/reeeper.js
forever stop app/workers/host-services.js

5
yarn.lock

@ -6064,6 +6064,11 @@ passport@^0.5.0:
passport-strategy "1.x.x"
pause "0.0.1"
password-generator@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/password-generator/-/password-generator-2.3.2.tgz#9626f778d64d26f7c2f73b64389407e28f62eecd"
integrity sha512-kJWUrdveSAqHCeWJWnv5vNc89hFHM5au+pvKja5+xCTxlRF3zQaecJlR6hSoOotAJtQ3otQq4/Q4iWc/TxsXhA==
path-dirname@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"

Loading…
Cancel
Save