Guest User

Untitled

a guest
May 25th, 2018
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.83 KB | None | 0 0
  1. 'use strict';
  2.  
  3. const bcrypt = require('bcrypt');
  4. const boom = require('boom');
  5. const joi = require('joi');
  6. const flatten = require('lodash/flatten');
  7. const pick = require('lodash/pick');
  8.  
  9. const models = require('../../models');
  10. const { AccessToken, App, User } = models;
  11.  
  12. const debug = require('debug')('microauth:test');
  13.  
  14. const loginSchema = joi
  15. .object({
  16. appname: joi.string().required(),
  17. email: joi.string().required(),
  18. password: joi.string().required(),
  19. })
  20. .required();
  21.  
  22. async function run(req, res, next) {
  23. const { appname, email, password } = joi.attempt(req.body, loginSchema);
  24.  
  25. const app = await getApp(appname);
  26. if (!app) {
  27. throw boom.badRequest(`Invalid app name: ${appname}.`);
  28. }
  29. if (app.isInactive()) {
  30. throw boom.badRequest('App is not active.');
  31. }
  32.  
  33. const { isAuthorized, user } = await authorize({ email, password });
  34. if (!user) {
  35. throw boom.notFound('User not found.');
  36. }
  37. debug(`User ${user.get('email')} is authorised? ${isAuthorized}`);
  38. if (!isAuthorized) {
  39. throw boom.unauthorized('Invalid email or password.');
  40. }
  41.  
  42. const { result } = await isUserBelongsToApp(user, app.get('name'));
  43. if (!result) {
  44. throw boom.badRequest(`User is not authorised to access app.`);
  45. }
  46.  
  47. return successResponse(email, app.get('secret'), res);
  48. }
  49.  
  50. async function getApp(name) {
  51. return await App.findOne({ name });
  52. }
  53.  
  54. async function authorize({ email, password }) {
  55. const user = await User.findOne(
  56. { email, status: 'active' },
  57. { withRelated: ['apps', 'roles.permissions'] }
  58. );
  59.  
  60. let isAuthorized = false;
  61. if (user) {
  62. isAuthorized = await bcrypt.compare(password, user.get('password'));
  63. }
  64. return { isAuthorized, user };
  65. }
  66.  
  67. async function isUserBelongsToApp(user, appname) {
  68. let result = false;
  69. let app = null;
  70. app = user.related('apps').findWhere({ name: appname });
  71. if (app) {
  72. result = true;
  73. }
  74. return { result, app };
  75. }
  76.  
  77. async function successResponse(email, secret, res) {
  78. const userFields = [
  79. 'device',
  80. 'email',
  81. 'firstname',
  82. 'language',
  83. 'lastname',
  84. 'phone',
  85. 'uid',
  86. ];
  87. const roleFields = ['name', 'description'];
  88. const permissionFields = ['name', 'object', 'action'];
  89.  
  90. let user = await User.findOne(
  91. {
  92. email: email,
  93. },
  94. {
  95. withRelated: ['roles.permissions'],
  96. }
  97. );
  98. user = user.toJSON();
  99. const result = Object.assign({}, { ...user });
  100. result.roles = [];
  101. result.permissions = [];
  102.  
  103. if (user.roles) {
  104. result.roles = user.roles.map(role => pick(role, roleFields));
  105. result.permissions = user.roles.map(role => {
  106. return role.permissions.map(permission =>
  107. pick(permission, permissionFields)
  108. );
  109. });
  110. }
  111. result.permissions = flatten(result.permissions);
  112. const { token, expiration } = new AccessToken(secret).create(result);
  113. res.json({ token, expiration });
  114. }
  115.  
  116. module.exports = run;
Add Comment
Please, Sign In to add comment