SamlLogHandler.mjs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { SamlLog } from '../../models/SamlLog.js'
  2. import SessionManager from '../Authentication/SessionManager.js'
  3. import logger from '@overleaf/logger'
  4. import loggerSerializers from '@overleaf/logger/serializers.js'
  5. import { callbackify } from 'node:util'
  6. import Settings from '@overleaf/settings'
  7. const ALLOWED_PATHS = Settings.saml?.logAllowList || ['/saml/']
  8. async function log(req, data, samlAssertion) {
  9. let providerId, sessionId
  10. data = data || {}
  11. try {
  12. const { path, query } = req
  13. if (!ALLOWED_PATHS.some(allowedPath => path.startsWith(allowedPath))) {
  14. return
  15. }
  16. const { saml } = req.session
  17. const userId = SessionManager.getLoggedInUserId(req.session)
  18. providerId = (req.session.saml?.providerId || '').toString()
  19. sessionId = (req.sessionID || '').toString().substr(0, 8)
  20. const samlLog = new SamlLog()
  21. samlLog.providerId = providerId
  22. samlLog.sessionId = sessionId
  23. samlLog.path = path
  24. samlLog.userId = userId
  25. data.query = query
  26. data.samlSession = saml
  27. if (data.error instanceof Error) {
  28. const errSerialized = loggerSerializers.err(data.error)
  29. if (data.error.tryAgain) {
  30. errSerialized.tryAgain = data.error.tryAgain
  31. }
  32. req.logger.addFields({ providerId, sessionId, userId })
  33. data.error = errSerialized
  34. }
  35. if (samlAssertion) {
  36. const samlAssertionForLog = {
  37. assertionXml: samlAssertion.getAssertionXml(),
  38. responseXml: samlAssertion.getSamlResponseXml(),
  39. assertionJsonExtended: req.user_info,
  40. }
  41. samlLog.samlAssertion = JSON.stringify(samlAssertionForLog)
  42. }
  43. if (data.error) {
  44. data.body = {}
  45. if (req.body.email) {
  46. data.body.email = req.body.email
  47. }
  48. if (req.body.SAMLResponse) {
  49. data.body.SAMLResponse = req.body.SAMLResponse
  50. }
  51. }
  52. try {
  53. samlLog.jsonData = JSON.stringify(data)
  54. } catch (err) {
  55. // log but continue on data errors
  56. logger.error(
  57. { err, sessionId, providerId },
  58. 'SamlLog JSON.stringify Error'
  59. )
  60. }
  61. await samlLog.save()
  62. } catch (err) {
  63. logger.error({ err, sessionId, providerId }, 'SamlLog Error')
  64. }
  65. }
  66. const SamlLogHandler = {
  67. log: callbackify(log),
  68. promises: {
  69. log,
  70. },
  71. }
  72. export default SamlLogHandler