builds register and firstRegister operations

This commit is contained in:
James
2020-04-16 15:57:34 -04:00
parent a31e0dce96
commit 2e5357420e
14 changed files with 181 additions and 60 deletions

View File

@@ -6,7 +6,7 @@ const url = config.serverURL;
const usernameField = config.user.auth.useAsUsername; const usernameField = config.user.auth.useAsUsername;
const globalSetup = async () => { const globalSetup = async () => {
global.PAYLOAD_SERVER = await server.start(); global.PAYLOAD_SERVER = server.start();
const response = await fetch(`${url}/api/first-register`, { const response = await fetch(`${url}/api/first-register`, {
body: JSON.stringify({ body: JSON.stringify({
@@ -20,6 +20,11 @@ const globalSetup = async () => {
}); });
const data = await response.json(); const data = await response.json();
if (!data.token) {
throw new Error('Failed to register first user');
}
global.AUTH_TOKEN = data.token; global.AUTH_TOKEN = data.token;
}; };

View File

@@ -1,17 +1,17 @@
const checkIfInitialized = require('./checkIfInitialized');
const login = require('./login'); const login = require('./login');
const refresh = require('./refresh'); const refresh = require('./refresh');
const register = require('./register'); const register = require('./register');
const init = require('./init'); const init = require('./init');
const forgotPassword = require('./forgotPassword'); const forgotPassword = require('./forgotPassword');
const resetPassword = require('./resetPassword'); const resetPassword = require('./resetPassword');
const registerFirstUser = require('./registerFirstUser');
module.exports = { module.exports = {
checkIfInitialized,
login, login,
refresh, refresh,
init, init,
register, register,
forgotPassword, forgotPassword,
resetPassword, resetPassword,
registerFirstUser,
}; };

View File

@@ -16,7 +16,7 @@ const login = async (args) => {
// 1. Execute before login hook // 1. Execute before login hook
// ///////////////////////////////////// // /////////////////////////////////////
const beforeLoginHook = args.config && args.config.hooks && args.config.hooks.beforeLogin; const beforeLoginHook = args.config.hooks && args.config.hooks.beforeLogin;
if (typeof beforeLoginHook === 'function') { if (typeof beforeLoginHook === 'function') {
options = await beforeLoginHook(options); options = await beforeLoginHook(options);
@@ -77,8 +77,8 @@ const login = async (args) => {
// ///////////////////////////////////// // /////////////////////////////////////
return token; return token;
} catch (err) { } catch (error) {
throw err; throw error;
} }
}; };

View File

@@ -14,7 +14,7 @@ const refresh = async (args) => {
// 1. Execute before refresh hook // 1. Execute before refresh hook
// ///////////////////////////////////// // /////////////////////////////////////
const beforeRefreshHook = args.config.user && args.config.user.hooks && args.config.user.hooks.beforeRefresh; const beforeRefreshHook = args.config.hooks && args.config.hooks.beforeRefresh;
if (typeof beforeRefreshHook === 'function') { if (typeof beforeRefreshHook === 'function') {
options = await beforeRefreshHook(options); options = await beforeRefreshHook(options);
@@ -24,9 +24,9 @@ const refresh = async (args) => {
// 2. Perform refresh // 2. Perform refresh
// ///////////////////////////////////// // /////////////////////////////////////
const secret = options.config.user.auth.secretKey; const secret = options.config.auth.secretKey;
const opts = {}; const opts = {};
opts.expiresIn = options.config.user.auth.tokenExpiration; opts.expiresIn = options.config.auth.tokenExpiration;
const token = options.authorization.replace('JWT ', ''); const token = options.authorization.replace('JWT ', '');
jwt.verify(token, secret, {}); jwt.verify(token, secret, {});
@@ -36,7 +36,7 @@ const refresh = async (args) => {
// 3. Execute after login hook // 3. Execute after login hook
// ///////////////////////////////////// // /////////////////////////////////////
const afterRefreshHook = args.config.user && args.config.user.hooks && args.config.user.hooks.afterRefresh; const afterRefreshHook = args.config.hooks && args.config.hooks.afterRefresh;
if (typeof afterRefreshHook === 'function') { if (typeof afterRefreshHook === 'function') {
await afterRefreshHook(options, refreshedToken); await afterRefreshHook(options, refreshedToken);

View File

@@ -0,0 +1,63 @@
const passport = require('passport');
const register = async (args) => {
try {
// Await validation here
let options = {
Model: args.Model,
config: args.config,
api: args.api,
data: args.data,
};
// /////////////////////////////////////
// 1. Execute before register hook
// /////////////////////////////////////
const beforeRegisterHook = args.config.hooks && args.config.hooks.beforeRegister;
if (typeof beforeRegisterHook === 'function') {
options = await beforeRegisterHook(options);
}
// /////////////////////////////////////
// 2. Perform register
// /////////////////////////////////////
const {
Model,
config,
data,
} = options;
const usernameField = config.auth.useAsUsername;
let result = await Model.register(new Model({
[usernameField]: data[usernameField],
}), data.password);
await passport.authenticate('local');
// /////////////////////////////////////
// 3. Execute after register hook
// /////////////////////////////////////
const afterRegisterHook = args.config.hooks && args.config.hooks.afterRegister;
if (typeof afterRegisterHook === 'function') {
result = await afterRegisterHook(options, result);
}
// /////////////////////////////////////
// 4. Return user
// /////////////////////////////////////
return result;
} catch (error) {
throw error;
}
};
module.exports = register;

View File

@@ -0,0 +1,63 @@
const register = require('./register');
const login = require('./login');
const { Forbidden } = require('../../errors');
const registerFirstUser = async (args) => {
try {
const count = await args.Model.countDocuments({});
if (count >= 1) throw new Forbidden();
// Await validation here
let options = {
Model: args.Model,
config: args.config,
api: args.api,
data: args.data,
};
// /////////////////////////////////////
// 1. Execute before register first user hook
// /////////////////////////////////////
const beforeRegisterHook = args.config.hooks && args.config.hooks.beforeFirstRegister;
if (typeof beforeRegisterHook === 'function') {
options = await beforeRegisterHook(options);
}
// /////////////////////////////////////
// 2. Perform register first user
// /////////////////////////////////////
let result = await register(options);
// /////////////////////////////////////
// 3. Execute after register hook
// /////////////////////////////////////
const afterRegisterHook = args.config.hooks && args.config.hooks.afterFirstRegister;
if (typeof afterRegisterHook === 'function') {
result = await afterRegisterHook(options, result);
}
// /////////////////////////////////////
// 4. Return user
// /////////////////////////////////////
const token = await login(options);
const results = {
...result,
token,
};
return results;
} catch (error) {
throw error;
}
};
module.exports = registerFirstUser;

View File

@@ -1,16 +0,0 @@
/**
* Middleware to check if there are any users present in the database.
* @param req
* @param res
* @param next
* @returns {*}
*/
const checkIfInitialized = User => (req, res, next) => {
User.countDocuments({}, (err, count) => {
if (err) res.status(500).json({ error: err });
if (count >= 1) return res.status(403).json({ initialized: true });
return next();
});
};
module.exports = checkIfInitialized;

View File

@@ -1,4 +1,3 @@
const checkIfInitialized = require('./checkIfInitialized');
const login = require('./login'); const login = require('./login');
const me = require('./me'); const me = require('./me');
const refresh = require('./refresh'); const refresh = require('./refresh');
@@ -6,14 +5,15 @@ const register = require('./register');
const init = require('./init'); const init = require('./init');
const forgotPassword = require('./forgotPassword'); const forgotPassword = require('./forgotPassword');
const resetPassword = require('./resetPassword'); const resetPassword = require('./resetPassword');
const registerFirstUser = require('./registerFirstUser');
module.exports = { module.exports = {
checkIfInitialized,
login, login,
me, me,
refresh, refresh,
init, init,
register, register,
forgotPassword, forgotPassword,
registerFirstUser,
resetPassword, resetPassword,
}; };

View File

@@ -6,7 +6,7 @@ const loginHandler = (User, config) => async (req, res) => {
try { try {
const token = await login({ const token = await login({
Model: User, Model: User,
config: config.user, config,
data: req.body, data: req.body,
api: 'REST', api: 'REST',
}); });

View File

@@ -10,7 +10,7 @@ const refreshHandler = config => async (req, res) => {
authorization: req.headers.authorization, authorization: req.headers.authorization,
}); });
res.status(200).json({ return res.status(200).json({
message: 'Token refresh successful', message: 'Token refresh successful',
refreshedToken, refreshedToken,
}); });

View File

@@ -1,32 +1,20 @@
const passport = require('passport');
const httpStatus = require('http-status'); const httpStatus = require('http-status');
const formatErrorResponse = require('../../express/responses/formatError'); const formatErrorResponse = require('../../express/responses/formatError');
const { register } = require('../operations');
/** const registerHandler = (User, config) => async (req, res) => {
* Returns User when succesfully registered
* @param req
* @param res
* @param next
* @returns {*}
*/
const register = (User, config) => async (req, res) => {
try { try {
const usernameField = config.user.auth.useAsUsername; const user = await register({
data: req.body,
const user = await User.register(new User({ Model: User,
[usernameField]: req.body[usernameField], config,
}), req.body.password); api: 'REST',
await passport.authenticate('local');
return res.status(httpStatus.CREATED).json({
[usernameField]: user[usernameField],
role: user.role,
createdAt: user.createdAt,
}); });
return res.status(201).json(user);
} catch (error) { } catch (error) {
return res.status(httpStatus.UNAUTHORIZED).json(formatErrorResponse(error)); return res.status(httpStatus.UNAUTHORIZED).json(formatErrorResponse(error));
} }
}; };
module.exports = register; module.exports = registerHandler;

View File

@@ -0,0 +1,20 @@
const httpStatus = require('http-status');
const formatErrorResponse = require('../../express/responses/formatError');
const { registerFirstUser } = require('../operations');
const registerFirstUserHandler = (User, config) => async (req, res) => {
try {
const firstUser = await registerFirstUser({
Model: User,
config,
api: 'REST',
data: req.body,
});
return res.status(201).json(firstUser);
} catch (error) {
return res.status(error.status || httpStatus.INTERNAL_SERVER_ERROR).json(formatErrorResponse(error));
}
};
module.exports = registerFirstUserHandler;

View File

@@ -6,7 +6,7 @@ const {
refresh, refresh,
me, me,
register, register,
checkIfInitialized, registerFirstUser,
forgotPassword, forgotPassword,
resetPassword, resetPassword,
} = require('./requestHandlers'); } = require('./requestHandlers');
@@ -14,19 +14,17 @@ const {
const router = express.Router(); const router = express.Router();
const authRoutes = (User, config, email) => { const authRoutes = (User, config, email) => {
const registerHandler = register(User, config);
router router
.route('/init') .route('/init')
.get(init(User)); .get(init(User));
router router
.route('/login') .route('/login')
.post(login(User, config)); .post(login(User, config.user));
router router
.route('/refresh') .route('/refresh')
.post(refresh(config)); .post(refresh(config.user));
router router
.route('/me') .route('/me')
@@ -34,15 +32,15 @@ const authRoutes = (User, config, email) => {
router router
.route(`/${config.user.slug}/register`) .route(`/${config.user.slug}/register`)
.post(registerHandler); .post(register(User, config.user));
router router
.route('/first-register') .route('/first-register')
.post(checkIfInitialized(User), registerHandler); .post(registerFirstUser(User, config.user));
router router
.route('/forgot') .route('/forgot')
.post(forgotPassword(User, config)); .post(forgotPassword(User, config, email));
router router
.route('/reset') .route('/reset')