Files
kami-parse-server/src/Controllers/UserController.js

163 lines
4.4 KiB
JavaScript
Raw Normal View History

import { randomString } from '../cryptoUtils';
import { inflate } from '../triggers';
import AdaptableController from './AdaptableController';
import MailAdapter from '../Adapters/Email/MailAdapter';
var DatabaseAdapter = require('../DatabaseAdapter');
2016-02-27 14:46:29 -05:00
var RestWrite = require('../RestWrite');
var hash = require('../password').hash;
var Auth = require('../Auth');
export class UserController extends AdaptableController {
constructor(adapter, appId, options = {}) {
super(adapter, appId, options);
}
validateAdapter(adapter) {
// Allow no adapter
if (!adapter && !this.shouldVerifyEmails) {
return;
}
super.validateAdapter(adapter);
}
expectedAdapterType() {
return MailAdapter;
}
get shouldVerifyEmails() {
return this.options.verifyUserEmails;
}
setEmailVerifyToken(user) {
if (this.shouldVerifyEmails) {
user._email_verify_token = randomString(25);
user.emailVerified = false;
}
}
verifyEmail(username, token) {
return new Promise((resolve, reject) => {
// Trying to verify email when not enabled
if (!this.shouldVerifyEmails) {
reject();
return;
}
var database = this.config.database;
database.collection('_User').then(coll => {
// Need direct database access because verification token is not a parse field
return coll.findAndModify({
username: username,
_email_verify_token: token,
}, null, {$set: {emailVerified: true}}, (err, doc) => {
if (err || !doc.value) {
reject(err);
} else {
resolve(doc.value);
}
});
});
});
}
checkResetTokenValidity(username, token) {
return new Promise((resolve, reject) => {
return this.config.database.collection('_User').then(coll => {
return coll.findOne({
username: username,
2016-02-27 14:46:29 -05:00
_perishable_token: token,
}, (err, doc) => {
2016-02-27 14:46:29 -05:00
if (err || !doc) {
reject(err);
} else {
2016-02-27 14:46:29 -05:00
resolve(doc);
}
});
});
});
}
2016-02-27 14:46:29 -05:00
sendVerificationEmail(user) {
if (!this.shouldVerifyEmails) {
return;
}
const token = encodeURIComponent(user._email_verify_token);
const username = encodeURIComponent(user.username);
let link = `${this.config.verifyEmailURL}?token=${token}&username=${username}`;
this.adapter.sendVerificationEmail({
appName: this.config.appName,
link: link,
user: inflate('_User', user),
});
}
setPasswordResetToken(email) {
var database = this.config.database;
2016-02-27 14:46:29 -05:00
var token = randomString(25);
return new Promise((resolve, reject) => {
return database.collection('_User').then(coll => {
// Need direct database access because verification token is not a parse field
return coll.findAndModify({
email: email,
}, null, {$set: {_perishable_token: token}}, (err, doc) => {
if (err || !doc.value) {
console.error(err);
reject(err);
} else {
doc.value._perishable_token = token;
resolve(doc.value);
}
});
});
});
}
sendPasswordResetEmail(email) {
if (!this.adapter) {
2016-02-27 14:46:29 -05:00
throw "Trying to send a reset password but no adapter is set";
// TODO: No adapter?
return;
}
2016-02-27 14:46:29 -05:00
return this.setPasswordResetToken(email).then((user) => {
const token = encodeURIComponent(user._perishable_token);
const username = encodeURIComponent(user.username);
let link = `${this.config.requestResetPasswordURL}?token=${token}&username=${username}`
2016-02-27 14:46:29 -05:00
this.adapter.sendPasswordResetEmail({
appName: this.config.appName,
2016-02-27 14:46:29 -05:00
link: link,
user: inflate('_User', user),
});
return Promise.resolve(user);
});
}
2016-02-27 14:46:29 -05:00
updatePassword(username, token, password, config) {
return this.checkResetTokenValidity(username, token).then(() => {
return updateUserPassword(username, token, password, this.config);
2016-02-27 14:46:29 -05:00
});
}
}
2016-02-27 14:46:29 -05:00
// Mark this private
function updateUserPassword(username, token, password, config) {
var write = new RestWrite(config, Auth.master(config), '_User', {
username: username,
_perishable_token: token
}, {password: password, _perishable_token: null }, undefined);
return write.execute();
}
export default UserController;