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.

243 lines
7.3 KiB

  1. 'use strict'
  2. /* global appconfig, appdata, db, winston */
  3. const LocalStrategy = require('passport-local').Strategy
  4. const GoogleStrategy = require('passport-google-oauth20').Strategy
  5. const WindowsLiveStrategy = require('passport-windowslive').Strategy
  6. const FacebookStrategy = require('passport-facebook').Strategy
  7. const GitHubStrategy = require('passport-github2').Strategy
  8. const SlackStrategy = require('passport-slack').Strategy
  9. const LdapStrategy = require('passport-ldapauth').Strategy
  10. const fs = require('fs')
  11. module.exports = function (passport) {
  12. // Serialization user methods
  13. passport.serializeUser(function (user, done) {
  14. done(null, user._id)
  15. })
  16. passport.deserializeUser(function (id, done) {
  17. db.User.findById(id).then((user) => {
  18. if (user) {
  19. done(null, user)
  20. } else {
  21. done(new Error('User not found.'), null)
  22. }
  23. return true
  24. }).catch((err) => {
  25. done(err, null)
  26. })
  27. })
  28. // Local Account
  29. if (!appdata.capabilities.manyAuthProviders || (appconfig.auth.local && appconfig.auth.local.enabled)) {
  30. passport.use('local',
  31. new LocalStrategy({
  32. usernameField: 'email',
  33. passwordField: 'password'
  34. },
  35. (uEmail, uPassword, done) => {
  36. db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => {
  37. if (user) {
  38. return user.validatePassword(uPassword).then(() => {
  39. return done(null, user) || true
  40. }).catch((err) => {
  41. return done(err, null)
  42. })
  43. } else {
  44. return done(new Error('INVALID_LOGIN'), null)
  45. }
  46. }).catch((err) => {
  47. done(err, null)
  48. })
  49. }
  50. ))
  51. }
  52. // Google ID
  53. if (appdata.capabilities.manyAuthProviders && appconfig.auth.google && appconfig.auth.google.enabled) {
  54. passport.use('google',
  55. new GoogleStrategy({
  56. clientID: appconfig.auth.google.clientId,
  57. clientSecret: appconfig.auth.google.clientSecret,
  58. callbackURL: appconfig.host + '/login/google/callback'
  59. },
  60. (accessToken, refreshToken, profile, cb) => {
  61. db.User.processProfile(profile).then((user) => {
  62. return cb(null, user) || true
  63. }).catch((err) => {
  64. return cb(err, null) || true
  65. })
  66. }
  67. ))
  68. }
  69. // Microsoft Accounts
  70. if (appdata.capabilities.manyAuthProviders && appconfig.auth.microsoft && appconfig.auth.microsoft.enabled) {
  71. passport.use('windowslive',
  72. new WindowsLiveStrategy({
  73. clientID: appconfig.auth.microsoft.clientId,
  74. clientSecret: appconfig.auth.microsoft.clientSecret,
  75. callbackURL: appconfig.host + '/login/ms/callback'
  76. },
  77. function (accessToken, refreshToken, profile, cb) {
  78. db.User.processProfile(profile).then((user) => {
  79. return cb(null, user) || true
  80. }).catch((err) => {
  81. return cb(err, null) || true
  82. })
  83. }
  84. ))
  85. }
  86. // Facebook
  87. if (appdata.capabilities.manyAuthProviders && appconfig.auth.facebook && appconfig.auth.facebook.enabled) {
  88. passport.use('facebook',
  89. new FacebookStrategy({
  90. clientID: appconfig.auth.facebook.clientId,
  91. clientSecret: appconfig.auth.facebook.clientSecret,
  92. callbackURL: appconfig.host + '/login/facebook/callback',
  93. profileFields: ['id', 'displayName', 'email']
  94. },
  95. function (accessToken, refreshToken, profile, cb) {
  96. db.User.processProfile(profile).then((user) => {
  97. return cb(null, user) || true
  98. }).catch((err) => {
  99. return cb(err, null) || true
  100. })
  101. }
  102. ))
  103. }
  104. // GitHub
  105. if (appdata.capabilities.manyAuthProviders && appconfig.auth.github && appconfig.auth.github.enabled) {
  106. passport.use('github',
  107. new GitHubStrategy({
  108. clientID: appconfig.auth.github.clientId,
  109. clientSecret: appconfig.auth.github.clientSecret,
  110. callbackURL: appconfig.host + '/login/github/callback',
  111. scope: [ 'user:email' ]
  112. },
  113. (accessToken, refreshToken, profile, cb) => {
  114. db.User.processProfile(profile).then((user) => {
  115. return cb(null, user) || true
  116. }).catch((err) => {
  117. return cb(err, null) || true
  118. })
  119. }
  120. ))
  121. }
  122. // Slack
  123. if (appdata.capabilities.manyAuthProviders && appconfig.auth.slack && appconfig.auth.slack.enabled) {
  124. passport.use('slack',
  125. new SlackStrategy({
  126. clientID: appconfig.auth.slack.clientId,
  127. clientSecret: appconfig.auth.slack.clientSecret,
  128. callbackURL: appconfig.host + '/login/slack/callback'
  129. },
  130. (accessToken, refreshToken, profile, cb) => {
  131. db.User.processProfile(profile).then((user) => {
  132. return cb(null, user) || true
  133. }).catch((err) => {
  134. return cb(err, null) || true
  135. })
  136. }
  137. ))
  138. }
  139. // LDAP
  140. if (appdata.capabilities.manyAuthProviders && appconfig.auth.ldap && appconfig.auth.ldap.enabled) {
  141. passport.use('ldapauth',
  142. new LdapStrategy({
  143. server: {
  144. url: appconfig.auth.ldap.url,
  145. bindDn: appconfig.auth.ldap.bindDn,
  146. bindCredentials: appconfig.auth.ldap.bindCredentials,
  147. searchBase: appconfig.auth.ldap.searchBase,
  148. searchFilter: appconfig.auth.ldap.searchFilter,
  149. searchAttributes: ['displayName', 'name', 'cn', 'mail'],
  150. tlsOptions: (appconfig.auth.ldap.tlsEnabled) ? {
  151. ca: [
  152. fs.readFileSync(appconfig.auth.ldap.tlsCertPath)
  153. ]
  154. } : {}
  155. },
  156. usernameField: 'email',
  157. passReqToCallback: false
  158. },
  159. (profile, cb) => {
  160. profile.provider = 'ldap'
  161. profile.id = profile.dn
  162. db.User.processProfile(profile).then((user) => {
  163. return cb(null, user) || true
  164. }).catch((err) => {
  165. return cb(err, null) || true
  166. })
  167. }
  168. ))
  169. }
  170. // Create users for first-time
  171. db.onReady.then(() => {
  172. db.User.findOne({ provider: 'local', email: 'guest' }).then((c) => {
  173. if (c < 1) {
  174. // Create root admin account
  175. winston.info('[AUTH] No administrator account found. Creating a new one...')
  176. db.User.hashPassword('admin123').then((pwd) => {
  177. return db.User.create({
  178. provider: 'local',
  179. email: appconfig.admin,
  180. name: 'Administrator',
  181. password: pwd,
  182. rights: [{
  183. role: 'admin',
  184. path: '/',
  185. exact: false,
  186. deny: false
  187. }]
  188. })
  189. }).then(() => {
  190. winston.info('[AUTH] Administrator account created successfully!')
  191. }).then(() => {
  192. if (appdata.capabilities.guest) {
  193. // Create guest account
  194. return db.User.create({
  195. provider: 'local',
  196. email: 'guest',
  197. name: 'Guest',
  198. password: '',
  199. rights: [{
  200. role: 'read',
  201. path: '/',
  202. exact: false,
  203. deny: !appconfig.public
  204. }]
  205. }).then(() => {
  206. winston.info('[AUTH] Guest account created successfully!')
  207. })
  208. } else {
  209. return true
  210. }
  211. }).catch((err) => {
  212. winston.error('[AUTH] An error occured while creating administrator/guest account:')
  213. winston.error(err)
  214. })
  215. }
  216. })
  217. return true
  218. })
  219. }