You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.0 KiB

  1. 'use strict'
  2. /* global wiki */
  3. const Promise = require('bluebird')
  4. const bcrypt = require('bcryptjs-then')
  5. const _ = require('lodash')
  6. /**
  7. * Users schema
  8. */
  9. module.exports = (sequelize, DataTypes) => {
  10. let userSchema = sequelize.define('user', {
  11. email: {
  12. type: DataTypes.STRING,
  13. allowNull: false,
  14. validate: {
  15. isEmail: true
  16. }
  17. },
  18. provider: {
  19. type: DataTypes.ENUM(wiki.data.authProviders),
  20. allowNull: false
  21. },
  22. providerId: {
  23. type: DataTypes.STRING,
  24. allowNull: true
  25. },
  26. password: {
  27. type: DataTypes.STRING,
  28. allowNull: true
  29. },
  30. name: {
  31. type: DataTypes.STRING,
  32. allowNull: true
  33. },
  34. role: {
  35. type: DataTypes.ENUM('admin', 'user', 'guest'),
  36. allowNull: false
  37. }
  38. }, {
  39. timestamps: true,
  40. version: true,
  41. indexes: [
  42. {
  43. unique: true,
  44. fields: ['provider', 'email']
  45. }
  46. ]
  47. })
  48. userSchema.prototype.validatePassword = function (rawPwd) {
  49. return bcrypt.compare(rawPwd, this.password).then((isValid) => {
  50. return (isValid) ? true : Promise.reject(new Error(wiki.lang.t('auth:errors:invalidlogin')))
  51. })
  52. }
  53. userSchema.processProfile = (profile) => {
  54. let primaryEmail = ''
  55. if (_.isArray(profile.emails)) {
  56. let e = _.find(profile.emails, ['primary', true])
  57. primaryEmail = (e) ? e.value : _.first(profile.emails).value
  58. } else if (_.isString(profile.email) && profile.email.length > 5) {
  59. primaryEmail = profile.email
  60. } else if (_.isString(profile.mail) && profile.mail.length > 5) {
  61. primaryEmail = profile.mail
  62. } else if (profile.user && profile.user.email && profile.user.email.length > 5) {
  63. primaryEmail = profile.user.email
  64. } else {
  65. return Promise.reject(new Error(wiki.lang.t('auth:errors.invaliduseremail')))
  66. }
  67. profile.provider = _.lowerCase(profile.provider)
  68. primaryEmail = _.toLower(primaryEmail)
  69. return wiki.db.User.findOneAndUpdate({
  70. email: primaryEmail,
  71. provider: profile.provider
  72. }, {
  73. email: primaryEmail,
  74. provider: profile.provider,
  75. providerId: profile.id,
  76. name: profile.displayName || _.split(primaryEmail, '@')[0]
  77. }, {
  78. new: true
  79. }).then((user) => {
  80. // Handle unregistered accounts
  81. if (!user && profile.provider !== 'local' && (appconfig.auth.defaultReadAccess || profile.provider === 'ldap' || profile.provider === 'azure')) {
  82. let nUsr = {
  83. email: primaryEmail,
  84. provider: profile.provider,
  85. providerId: profile.id,
  86. password: '',
  87. name: profile.displayName || profile.name || profile.cn,
  88. rights: [{
  89. role: 'read',
  90. path: '/',
  91. exact: false,
  92. deny: false
  93. }]
  94. }
  95. return wiki.db.User.create(nUsr)
  96. }
  97. return user || Promise.reject(new Error(wiki.lang.t('auth:errors:notyetauthorized')))
  98. })
  99. }
  100. userSchema.hashPassword = (rawPwd) => {
  101. return bcrypt.hash(rawPwd)
  102. }
  103. return userSchema
  104. }