UserAuditLogHandler.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. const OError = require('@overleaf/o-error')
  2. const { UserAuditLogEntry } = require('../../models/UserAuditLogEntry')
  3. const { callbackify } = require('util')
  4. function _canHaveNoIpAddressId(operation, info) {
  5. if (operation === 'join-group-subscription') return true
  6. if (operation === 'leave-group-subscription') return true
  7. if (operation === 'must-reset-password-set') return true
  8. if (operation === 'remove-email' && info.script) return true
  9. return false
  10. }
  11. function _canHaveNoInitiatorId(operation, info) {
  12. if (operation === 'reset-password') return true
  13. if (operation === 'unlink-sso' && info.providerId === 'collabratec')
  14. return true
  15. if (operation === 'unlink-sso' && info.script === true) return true
  16. if (operation === 'unlink-institution-sso-not-migrated') return true
  17. if (operation === 'remove-email' && info.script) return true
  18. if (operation === 'join-group-subscription') return true
  19. if (operation === 'leave-group-subscription') return true
  20. if (operation === 'must-reset-password-set') return true
  21. if (operation === 'must-reset-password-unset') return true
  22. if (operation === 'account-suspension' && info.script) return true
  23. }
  24. /**
  25. * Add an audit log entry
  26. *
  27. * The entry should include at least the following fields:
  28. *
  29. * - userId: the user on behalf of whom the operation was performed
  30. * - operation: a string identifying the type of operation
  31. * - initiatorId: who performed the operation
  32. * - ipAddress: the IP address of the initiator
  33. * - info: an object detailing what happened
  34. */
  35. async function addEntry(userId, operation, initiatorId, ipAddress, info = {}) {
  36. if (!operation) {
  37. throw new OError('missing operation for audit log', {
  38. initiatorId,
  39. ipAddress,
  40. })
  41. }
  42. if (!ipAddress && !_canHaveNoIpAddressId(operation, info)) {
  43. throw new OError('missing ipAddress for audit log', {
  44. operation,
  45. initiatorId,
  46. })
  47. }
  48. if (!initiatorId && !_canHaveNoInitiatorId(operation, info)) {
  49. throw new OError('missing initiatorId for audit log', {
  50. operation,
  51. ipAddress,
  52. })
  53. }
  54. const entry = {
  55. userId,
  56. operation,
  57. initiatorId,
  58. info,
  59. ipAddress,
  60. }
  61. await UserAuditLogEntry.create(entry)
  62. }
  63. const UserAuditLogHandler = {
  64. addEntry: callbackify(addEntry),
  65. promises: {
  66. addEntry,
  67. },
  68. }
  69. module.exports = UserAuditLogHandler