47 lines
1.5 KiB
JavaScript
47 lines
1.5 KiB
JavaScript
const { isAdminRole } = require('./auth');
|
|
|
|
/**
|
|
* Who may use a source for playback and API access.
|
|
* ownerId null/undefined: legacy shared — any authenticated user may use it.
|
|
* ownerId N: only that user id (and admins) may use it.
|
|
*/
|
|
function canUserAccessSource(user, source) {
|
|
if (!user || !source) return false;
|
|
if (isAdminRole(user)) return true;
|
|
const oid = source.ownerId;
|
|
if (oid == null || oid === undefined) return true;
|
|
const uid = user.id != null ? Number(user.id) : NaN;
|
|
const oidN = Number(oid);
|
|
return !Number.isNaN(uid) && !Number.isNaN(oidN) && oidN === uid;
|
|
}
|
|
|
|
async function getAccessibleSourceIds(req, sourcesApi) {
|
|
const all = await sourcesApi.getAll();
|
|
return all.filter((s) => canUserAccessSource(req.user, s)).map((s) => s.id);
|
|
}
|
|
|
|
/** Returns false after sending res if missing, forbidden, or invalid. */
|
|
async function assertCanUseSourceById(req, res, sourcesApi, rawSourceId) {
|
|
const sid = typeof rawSourceId === 'number' ? rawSourceId : parseInt(rawSourceId, 10);
|
|
if (Number.isNaN(sid)) {
|
|
res.status(400).json({ error: 'Invalid source id' });
|
|
return false;
|
|
}
|
|
const source = await sourcesApi.getById(sid);
|
|
if (!source) {
|
|
res.status(404).json({ error: 'Source not found' });
|
|
return false;
|
|
}
|
|
if (!canUserAccessSource(req.user, source)) {
|
|
res.status(403).json({ error: 'No access to this source' });
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
module.exports = {
|
|
canUserAccessSource,
|
|
getAccessibleSourceIds,
|
|
assertCanUseSourceById
|
|
};
|