UserAuditLogHandler.js 1.5 KB

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