Allow users to create ereaders (#3531)

* add create eReader permission toggle

* add english label for create EReader permission

* add ereader table to account with user specific modal

* add createEreader permission

* create api endpoint and logic for updating user eReader devices

* add translated label for createEreader permission

* handle name duplicates and remove helper func

* toast for duplicate name error caught on server

* restrict user ereader updates to devices with sole ownership

* remove label

* fix other devices logic and client socket emitter

* fix for deleting ereaders

* User create ereader endpoint validate accessibility

---------

Co-authored-by: advplyr <advplyr@protonmail.com>
This commit is contained in:
Austin Spencer 2024-10-26 16:34:34 -04:00 committed by GitHub
parent 6905b288d2
commit ecc30b85bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 354 additions and 3 deletions

View file

@ -394,6 +394,58 @@ class MeController {
res.json(req.user.toOldJSONForBrowser())
}
/**
* POST: /api/me/ereader-devices
*
* @param {RequestWithUser} req
* @param {Response} res
*/
async updateUserEReaderDevices(req, res) {
if (!req.body.ereaderDevices || !Array.isArray(req.body.ereaderDevices)) {
return res.status(400).send('Invalid payload. ereaderDevices array required')
}
const userEReaderDevices = req.body.ereaderDevices
for (const device of userEReaderDevices) {
if (!device.name || !device.email) {
return res.status(400).send('Invalid payload. ereaderDevices array items must have name and email')
} else if (device.availabilityOption !== 'specificUsers' || device.users?.length !== 1 || device.users[0] !== req.user.id) {
return res.status(400).send('Invalid payload. ereaderDevices array items must have availabilityOption "specificUsers" and only the current user')
}
}
const otherDevices = Database.emailSettings.ereaderDevices.filter((device) => {
return !Database.emailSettings.checkUserCanAccessDevice(device, req.user) || device.users?.length !== 1
})
const ereaderDevices = otherDevices.concat(userEReaderDevices)
// Check for duplicate names
const nameSet = new Set()
const hasDupes = ereaderDevices.some((device) => {
if (nameSet.has(device.name)) {
return true // Duplicate found
}
nameSet.add(device.name)
return false
})
if (hasDupes) {
return res.status(400).send('Invalid payload. Duplicate "name" field found.')
}
const updated = Database.emailSettings.update({ ereaderDevices })
if (updated) {
await Database.updateSetting(Database.emailSettings)
SocketAuthority.clientEmitter(req.user.id, 'ereader-devices-updated', {
ereaderDevices: Database.emailSettings.ereaderDevices
})
}
res.json({
ereaderDevices: Database.emailSettings.getEReaderDevices(req.user)
})
}
/**
* GET: /api/me/stats/year/:year
*