Added manticore sync API.
This commit is contained in:
@@ -44,7 +44,7 @@
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
v-if="user?.abilities?.some((ability) => ability.plainUrls)"
|
v-if="user?.abilities?.some((ability) => ability.subject === 'plainUrls')"
|
||||||
:href="entity.url"
|
:href="entity.url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
:href="user?.abilities?.some((ability) => ability.plainUrls) ? scene.url : scene.watchUrl"
|
:href="user?.abilities?.some((ability) => ability.subject === 'plainUrls') ? scene.url : scene.watchUrl"
|
||||||
:title="scene.date ? formatDate(scene.date.toISOString(), 'y-MM-dd hh:mm') : `Release date unknown, added ${formatDate(scene.createdAt, 'y-MM-dd')}`"
|
:title="scene.date ? formatDate(scene.date.toISOString(), 'y-MM-dd hh:mm') : `Release date unknown, added ${formatDate(scene.createdAt, 'y-MM-dd')}`"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="date nolink"
|
class="date nolink"
|
||||||
|
|||||||
@@ -203,6 +203,8 @@ export async function verifyKey(userId, key, req) {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
// no need to wait for this
|
// no need to wait for this
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return fetchUser(storedKey.user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createKey(reqUser) {
|
export async function createKey(reqUser) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import initRestrictionHandler from './restrictions.js';
|
|||||||
|
|
||||||
import { scenesRouter } from './scenes.js';
|
import { scenesRouter } from './scenes.js';
|
||||||
import { actorsRouter } from './actors.js';
|
import { actorsRouter } from './actors.js';
|
||||||
|
import { syncRouter } from './sync.js';
|
||||||
|
|
||||||
import { fetchMoviesApi } from './movies.js';
|
import { fetchMoviesApi } from './movies.js';
|
||||||
import { fetchEntitiesApi } from './entities.js';
|
import { fetchEntitiesApi } from './entities.js';
|
||||||
@@ -122,11 +123,7 @@ export default async function initServer() {
|
|||||||
|
|
||||||
router.use('/api/*', async (req, _res, next) => {
|
router.use('/api/*', async (req, _res, next) => {
|
||||||
if (req.headers['api-user']) {
|
if (req.headers['api-user']) {
|
||||||
await verifyKey(req.headers['api-user'], req.headers['api-key'], req);
|
req.user = await verifyKey(req.headers['api-user'], req.headers['api-key'], req);
|
||||||
|
|
||||||
req.user = { // eslint-disable-line no-param-reassign
|
|
||||||
id: Number(req.headers['api-user']),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
@@ -150,6 +147,7 @@ export default async function initServer() {
|
|||||||
router.use(alertsRouter);
|
router.use(alertsRouter);
|
||||||
router.use(scenesRouter);
|
router.use(scenesRouter);
|
||||||
router.use(actorsRouter);
|
router.use(actorsRouter);
|
||||||
|
router.use(syncRouter);
|
||||||
|
|
||||||
// MOVIES
|
// MOVIES
|
||||||
router.get('/api/movies', fetchMoviesApi);
|
router.get('/api/movies', fetchMoviesApi);
|
||||||
|
|||||||
49
src/web/sync.js
Normal file
49
src/web/sync.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import Router from 'express-promise-router';
|
||||||
|
|
||||||
|
import {
|
||||||
|
syncScenes,
|
||||||
|
syncMovies,
|
||||||
|
syncActors,
|
||||||
|
syncStashes,
|
||||||
|
} from '../sync.js';
|
||||||
|
|
||||||
|
import verifyAbility from '../../utils/verify-ability.js';
|
||||||
|
|
||||||
|
export const syncRouter = Router();
|
||||||
|
|
||||||
|
async function syncScenesApi(req, res) {
|
||||||
|
verifyAbility(req.user, 'sync', null, { throwError: true });
|
||||||
|
|
||||||
|
await syncScenes(req.body.sceneIds);
|
||||||
|
|
||||||
|
res.status(204).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncMoviesApi(req, res) {
|
||||||
|
verifyAbility(req.user, 'sync', null, { throwError: true });
|
||||||
|
|
||||||
|
await syncMovies(req.body.movieIds);
|
||||||
|
|
||||||
|
res.status(204).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncActorsApi(req, res) {
|
||||||
|
verifyAbility(req.user, 'sync', null, { throwError: true });
|
||||||
|
|
||||||
|
await syncActors(req.body.actorIds);
|
||||||
|
|
||||||
|
res.status(204).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncStashesApi(req, res) {
|
||||||
|
verifyAbility(req.user, 'sync', null, { throwError: true });
|
||||||
|
|
||||||
|
await syncStashes(req.body.stashIds);
|
||||||
|
|
||||||
|
res.status(204).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
syncRouter.post('/api/sync/scenes', syncScenesApi);
|
||||||
|
syncRouter.post('/api/sync/movies', syncMoviesApi);
|
||||||
|
syncRouter.post('/api/sync/actors', syncActorsApi);
|
||||||
|
syncRouter.post('/api/sync/stashes', syncStashesApi);
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
export default function verifyAbility(user, subject, action) {
|
import { HttpError } from '../src/errors.js';
|
||||||
|
|
||||||
|
function checkAbility(user, subject, action) {
|
||||||
if (!user?.abilities) {
|
if (!user?.abilities) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -8,8 +10,18 @@ export default function verifyAbility(user, subject, action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (subject) {
|
if (subject) {
|
||||||
return user.abilities.some((ability) => ability[subject] === true);
|
return user.abilities.some((ability) => ability[subject] === true || (ability.subject === subject && !ability.action));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function verifyAbility(user, subject, action, options = {}) {
|
||||||
|
const isAble = checkAbility(user, subject, action);
|
||||||
|
|
||||||
|
if (!isAble && options.throwError) {
|
||||||
|
throw new HttpError(`Insufficient privileges for ${[subject, action].filter(Boolean).join()}`, 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isAble;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user