mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const Logger = require('../../Logger')
 | 
						|
const { areEquivalent, copyValue, isNullOrNaN } = require('../../utils')
 | 
						|
 | 
						|
/**
 | 
						|
 * @typedef EreaderDeviceObject
 | 
						|
 * @property {string} name
 | 
						|
 * @property {string} email
 | 
						|
 * @property {string} availabilityOption
 | 
						|
 * @property {string[]} users
 | 
						|
 */
 | 
						|
 | 
						|
// REF: https://nodemailer.com/smtp/
 | 
						|
class EmailSettings {
 | 
						|
  constructor(settings = null) {
 | 
						|
    this.id = 'email-settings'
 | 
						|
    this.host = null
 | 
						|
    this.port = 465
 | 
						|
    this.secure = true
 | 
						|
    this.user = null
 | 
						|
    this.pass = null
 | 
						|
    this.testAddress = null
 | 
						|
    this.fromAddress = null
 | 
						|
 | 
						|
    /** @type {EreaderDeviceObject[]} */
 | 
						|
    this.ereaderDevices = []
 | 
						|
 | 
						|
    if (settings) {
 | 
						|
      this.construct(settings)
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  construct(settings) {
 | 
						|
    this.host = settings.host
 | 
						|
    this.port = settings.port
 | 
						|
    this.secure = !!settings.secure
 | 
						|
    this.user = settings.user
 | 
						|
    this.pass = settings.pass
 | 
						|
    this.testAddress = settings.testAddress
 | 
						|
    this.fromAddress = settings.fromAddress
 | 
						|
    this.ereaderDevices = settings.ereaderDevices?.map(d => ({ ...d })) || []
 | 
						|
  }
 | 
						|
 | 
						|
  toJSON() {
 | 
						|
    return {
 | 
						|
      id: this.id,
 | 
						|
      host: this.host,
 | 
						|
      port: this.port,
 | 
						|
      secure: this.secure,
 | 
						|
      user: this.user,
 | 
						|
      pass: this.pass,
 | 
						|
      testAddress: this.testAddress,
 | 
						|
      fromAddress: this.fromAddress,
 | 
						|
      ereaderDevices: this.ereaderDevices.map(d => ({ ...d }))
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  update(payload) {
 | 
						|
    if (!payload) return false
 | 
						|
 | 
						|
    if (payload.port !== undefined) {
 | 
						|
      if (isNullOrNaN(payload.port)) payload.port = 465
 | 
						|
      else payload.port = Number(payload.port)
 | 
						|
    }
 | 
						|
    if (payload.secure !== undefined) payload.secure = !!payload.secure
 | 
						|
 | 
						|
    if (payload.ereaderDevices !== undefined && !Array.isArray(payload.ereaderDevices)) payload.ereaderDevices = undefined
 | 
						|
 | 
						|
    if (payload.ereaderDevices?.length) {
 | 
						|
      // Validate ereader devices
 | 
						|
      payload.ereaderDevices = payload.ereaderDevices.map((device) => {
 | 
						|
        if (!device.name || !device.email) {
 | 
						|
          Logger.error(`[EmailSettings] Update ereader device is invalid`, device)
 | 
						|
          return null
 | 
						|
        }
 | 
						|
        if (!device.availabilityOption || !['adminOrUp', 'userOrUp', 'guestOrUp', 'specificUsers'].includes(device.availabilityOption)) {
 | 
						|
          device.availabilityOption = 'adminOrUp'
 | 
						|
        }
 | 
						|
        if (device.availabilityOption === 'specificUsers' && !device.users?.length) {
 | 
						|
          device.availabilityOption = 'adminOrUp'
 | 
						|
        }
 | 
						|
        if (device.availabilityOption !== 'specificUsers' && device.users?.length) {
 | 
						|
          device.users = []
 | 
						|
        }
 | 
						|
        return device
 | 
						|
      }).filter(d => d)
 | 
						|
    }
 | 
						|
 | 
						|
    let hasUpdates = false
 | 
						|
 | 
						|
    const json = this.toJSON()
 | 
						|
    for (const key in json) {
 | 
						|
      if (key === 'id') continue
 | 
						|
 | 
						|
      if (payload[key] !== undefined && !areEquivalent(payload[key], json[key])) {
 | 
						|
        this[key] = copyValue(payload[key])
 | 
						|
        hasUpdates = true
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return hasUpdates
 | 
						|
  }
 | 
						|
 | 
						|
  getTransportObject() {
 | 
						|
    const payload = {
 | 
						|
      host: this.host,
 | 
						|
      secure: this.secure
 | 
						|
    }
 | 
						|
    // Only set to true for port 465 (https://nodemailer.com/smtp/#tls-options)
 | 
						|
    if (this.port !== 465) {
 | 
						|
      payload.secure = false
 | 
						|
    }
 | 
						|
    if (this.port) payload.port = this.port
 | 
						|
    if (this.user && this.pass !== undefined) {
 | 
						|
      payload.auth = {
 | 
						|
        user: this.user,
 | 
						|
        pass: this.pass
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return payload
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * 
 | 
						|
   * @param {EreaderDeviceObject} device 
 | 
						|
   * @param {import('../user/User')} user 
 | 
						|
   * @returns {boolean}
 | 
						|
   */
 | 
						|
  checkUserCanAccessDevice(device, user) {
 | 
						|
    let deviceAvailability = device.availabilityOption || 'adminOrUp'
 | 
						|
    if (deviceAvailability === 'adminOrUp' && user.isAdminOrUp) return true
 | 
						|
    if (deviceAvailability === 'userOrUp' && (user.isAdminOrUp || user.isUser)) return true
 | 
						|
    if (deviceAvailability === 'guestOrUp') return true
 | 
						|
    if (deviceAvailability === 'specificUsers') {
 | 
						|
      let deviceUsers = device.users || []
 | 
						|
      return deviceUsers.includes(user.id)
 | 
						|
    }
 | 
						|
    return false
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get ereader devices accessible to user
 | 
						|
   * 
 | 
						|
   * @param {import('../user/User')} user 
 | 
						|
   * @returns {EreaderDeviceObject[]}
 | 
						|
   */
 | 
						|
  getEReaderDevices(user) {
 | 
						|
    return this.ereaderDevices.filter((device) => this.checkUserCanAccessDevice(device, user))
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get ereader device by name
 | 
						|
   * 
 | 
						|
   * @param {string} deviceName 
 | 
						|
   * @returns {EreaderDeviceObject}
 | 
						|
   */
 | 
						|
  getEReaderDevice(deviceName) {
 | 
						|
    return this.ereaderDevices.find(d => d.name === deviceName)
 | 
						|
  }
 | 
						|
}
 | 
						|
module.exports = EmailSettings |