Added functional stash button on scene tiles.
This commit is contained in:
@@ -5,7 +5,7 @@ import fs from 'fs/promises';
|
||||
import { createAvatar } from '@dicebear/core';
|
||||
import { shapes } from '@dicebear/collection';
|
||||
|
||||
import knex from './knex.js';
|
||||
import { knexOwner as knex } from './knex.js';
|
||||
import { curateUser, fetchUser } from './users.js';
|
||||
import { HttpError } from './errors.js';
|
||||
|
||||
@@ -38,7 +38,7 @@ async function generateAvatar(user) {
|
||||
|
||||
export async function login(credentials) {
|
||||
if (!config.auth.login) {
|
||||
throw new HttpError('Authentication is disabled', 405);
|
||||
throw new HttpError('Logins are currently disabled', 405);
|
||||
}
|
||||
|
||||
const user = await fetchUser(credentials.username.trim(), {
|
||||
@@ -46,6 +46,8 @@ export async function login(credentials) {
|
||||
raw: true,
|
||||
});
|
||||
|
||||
console.log('login user', user);
|
||||
|
||||
if (!user) {
|
||||
throw new HttpError('Username or password incorrect', 401);
|
||||
}
|
||||
@@ -60,12 +62,13 @@ export async function login(credentials) {
|
||||
await generateAvatar(user);
|
||||
}
|
||||
|
||||
// fetched the raw user for password verification, don't return directly to user
|
||||
return curateUser(user);
|
||||
}
|
||||
|
||||
export async function signup(credentials) {
|
||||
if (!config.auth.signup) {
|
||||
throw new HttpError('Authentication is disabled', 405);
|
||||
throw new HttpError('Sign-ups are currently disabled', 405);
|
||||
}
|
||||
|
||||
const curatedUsername = credentials.username.trim();
|
||||
|
||||
13
src/knex.js
13
src/knex.js
@@ -1,7 +1,16 @@
|
||||
import config from 'config';
|
||||
import knex from 'knex';
|
||||
|
||||
export default knex({
|
||||
export const knexQuery = knex({
|
||||
client: 'pg',
|
||||
connection: config.database.query,
|
||||
pool: config.database.pool,
|
||||
// performance overhead, don't use asyncStackTraces in production
|
||||
asyncStackTraces: process.env.NODE_ENV === 'development',
|
||||
// debug: process.env.NODE_ENV === 'development',
|
||||
});
|
||||
|
||||
export const knexOwner = knex({
|
||||
client: 'pg',
|
||||
connection: config.database.owner,
|
||||
pool: config.database.pool,
|
||||
@@ -9,3 +18,5 @@ export default knex({
|
||||
asyncStackTraces: process.env.NODE_ENV === 'development',
|
||||
// debug: process.env.NODE_ENV === 'development',
|
||||
});
|
||||
|
||||
export default knexQuery;
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import config from 'config';
|
||||
|
||||
import knex from './knex.js';
|
||||
import { knexOwner as knex } from './knex.js';
|
||||
import { searchApi } from './manticore.js';
|
||||
import { HttpError } from './errors.js';
|
||||
import { fetchActorsById, curateActor, sortActorsByGender } from './actors.js';
|
||||
import { fetchTagsById } from './tags.js';
|
||||
import { fetchEntitiesById } from './entities.js';
|
||||
import { curateStash } from './stashes.js';
|
||||
|
||||
function curateMedia(media) {
|
||||
if (!media) {
|
||||
@@ -66,14 +67,15 @@ function curateScene(rawScene, assets) {
|
||||
})),
|
||||
poster: curateMedia(assets.poster),
|
||||
photos: assets.photos.map((photo) => curateMedia(photo)),
|
||||
stashes: assets.stashes?.map((stash) => curateStash(stash)) || [],
|
||||
createdBatchId: rawScene.created_batch_id,
|
||||
updatedBatchId: rawScene.updated_batch_id,
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchScenesById(sceneIds) {
|
||||
const [scenes, channels, actors, directors, tags, posters, photos] = await Promise.all([
|
||||
knex('releases').whereIn('id', sceneIds),
|
||||
export async function fetchScenesById(sceneIds, reqUser) {
|
||||
const [scenes, channels, actors, directors, tags, posters, photos, stashes] = await Promise.all([
|
||||
knex('releases').whereIn('releases.id', sceneIds),
|
||||
knex('releases')
|
||||
.select('channels.*', 'networks.id as network_id', 'networks.slug as network_slug', 'networks.name as network_name', 'networks.type as network_type')
|
||||
.whereIn('releases.id', sceneIds)
|
||||
@@ -92,9 +94,9 @@ export async function fetchScenesById(sceneIds) {
|
||||
knex.raw('COALESCE(residence_countries.alias, residence_countries.name) as residence_country_name'),
|
||||
*/
|
||||
)
|
||||
.whereIn('release_id', sceneIds)
|
||||
.leftJoin('actors', 'actors.id', 'releases_actors.actor_id')
|
||||
.leftJoin('actors_meta', 'actors_meta.actor_id', 'actors.id'),
|
||||
.leftJoin('actors_meta', 'actors_meta.actor_id', 'actors.id')
|
||||
.whereIn('release_id', sceneIds),
|
||||
/*
|
||||
.leftJoin('countries as birth_countries', 'birth_countries.alpha2', 'actors_meta.birth_country_alpha2')
|
||||
.leftJoin('countries as residence_countries', 'residence_countries.alpha2', 'actors_meta.residence_country_alpha2'),
|
||||
@@ -104,9 +106,9 @@ export async function fetchScenesById(sceneIds) {
|
||||
.leftJoin('actors as directors', 'directors.id', 'releases_directors.director_id'),
|
||||
knex('releases_tags')
|
||||
.select('id', 'slug', 'name', 'release_id')
|
||||
.leftJoin('tags', 'tags.id', 'releases_tags.tag_id')
|
||||
.whereNotNull('tags.id')
|
||||
.whereIn('release_id', sceneIds)
|
||||
.leftJoin('tags', 'tags.id', 'releases_tags.tag_id')
|
||||
.orderBy('priority', 'desc'),
|
||||
knex('releases_posters')
|
||||
.whereIn('release_id', sceneIds)
|
||||
@@ -114,6 +116,12 @@ export async function fetchScenesById(sceneIds) {
|
||||
knex('releases_photos')
|
||||
.whereIn('release_id', sceneIds)
|
||||
.leftJoin('media', 'media.id', 'releases_photos.media_id'),
|
||||
reqUser
|
||||
? knex('stashes_scenes')
|
||||
.leftJoin('stashes', 'stashes.id', 'stashes_scenes.stash_id')
|
||||
.where('stashes.user_id', reqUser.id)
|
||||
.whereIn('stashes_scenes.scene_id', sceneIds)
|
||||
: [],
|
||||
]);
|
||||
|
||||
return sceneIds.map((sceneId) => {
|
||||
@@ -129,6 +137,7 @@ export async function fetchScenesById(sceneIds) {
|
||||
const sceneTags = tags.filter((tag) => tag.release_id === sceneId);
|
||||
const scenePoster = posters.find((poster) => poster.release_id === sceneId);
|
||||
const scenePhotos = photos.filter((photo) => photo.release_id === sceneId);
|
||||
const sceneStashes = stashes.filter((stash) => stash.scene_id === sceneId);
|
||||
|
||||
return curateScene(scene, {
|
||||
channel: sceneChannel,
|
||||
@@ -137,6 +146,7 @@ export async function fetchScenesById(sceneIds) {
|
||||
tags: sceneTags,
|
||||
poster: scenePoster,
|
||||
photos: scenePhotos,
|
||||
stashes: sceneStashes,
|
||||
});
|
||||
}).filter(Boolean);
|
||||
}
|
||||
@@ -294,7 +304,7 @@ function countAggregations(buckets) {
|
||||
return Object.fromEntries(buckets.map((bucket) => [bucket.key, { count: bucket.doc_count }]));
|
||||
}
|
||||
|
||||
export async function fetchScenes(filters, rawOptions) {
|
||||
export async function fetchScenes(filters, rawOptions, reqUser) {
|
||||
const options = curateOptions(rawOptions);
|
||||
const { query, sort } = buildQuery(filters);
|
||||
|
||||
@@ -302,6 +312,8 @@ export async function fetchScenes(filters, rawOptions) {
|
||||
console.log('options', options);
|
||||
console.log('query', query.bool.must);
|
||||
|
||||
console.log('request user', reqUser);
|
||||
|
||||
console.time('manticore');
|
||||
|
||||
const result = await searchApi.search({
|
||||
@@ -329,8 +341,6 @@ export async function fetchScenes(filters, rawOptions) {
|
||||
|
||||
console.timeEnd('manticore');
|
||||
|
||||
console.log('hits', result.hits.hits.length);
|
||||
|
||||
const actorCounts = options.aggregateActors && countAggregations(result.aggregations?.actorIds?.buckets);
|
||||
const tagCounts = options.aggregateTags && countAggregations(result.aggregations?.tagIds?.buckets);
|
||||
const channelCounts = options.aggregateChannels && countAggregations(result.aggregations?.channelIds?.buckets);
|
||||
@@ -346,7 +356,7 @@ export async function fetchScenes(filters, rawOptions) {
|
||||
console.timeEnd('fetch aggregations');
|
||||
|
||||
const sceneIds = result.hits.hits.map((hit) => Number(hit._id));
|
||||
const scenes = await fetchScenesById(sceneIds);
|
||||
const scenes = await fetchScenesById(sceneIds, reqUser);
|
||||
|
||||
return {
|
||||
scenes,
|
||||
|
||||
227
src/stashes.js
Executable file
227
src/stashes.js
Executable file
@@ -0,0 +1,227 @@
|
||||
import config from 'config';
|
||||
|
||||
import { knexOwner as knex } from './knex.js';
|
||||
import { HttpError } from './errors.js';
|
||||
import slugify from './utils/slugify.js';
|
||||
import initLogger from './logger.js';
|
||||
|
||||
const logger = initLogger();
|
||||
|
||||
let lastActorsViewRefresh = 0;
|
||||
|
||||
export function curateStash(stash) {
|
||||
if (!stash) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const curatedStash = {
|
||||
id: stash.id,
|
||||
name: stash.name,
|
||||
slug: stash.slug,
|
||||
primary: stash.primary,
|
||||
public: stash.public,
|
||||
createdAt: stash.created_at,
|
||||
stashedScenes: stash.stashed_scenes || null,
|
||||
stashedMovies: stash.stashed_movies || null,
|
||||
stashedActors: stash.stashed_actors || null,
|
||||
};
|
||||
|
||||
return curatedStash;
|
||||
}
|
||||
|
||||
function curateStashEntry(stash, user) {
|
||||
const curatedStashEntry = {
|
||||
user_id: user.id,
|
||||
name: stash.name,
|
||||
slug: slugify(stash.name),
|
||||
public: false,
|
||||
};
|
||||
|
||||
return curatedStashEntry;
|
||||
}
|
||||
|
||||
export async function fetchStash(stashId, sessionUser) {
|
||||
if (!sessionUser) {
|
||||
throw new HttpError('You are not authenthicated', 401);
|
||||
}
|
||||
|
||||
const stash = await knex('stashes')
|
||||
.where({
|
||||
id: stashId,
|
||||
user_id: sessionUser.id,
|
||||
})
|
||||
.first();
|
||||
|
||||
if (!stash) {
|
||||
throw new HttpError('You are not authorized to access this stash', 403);
|
||||
}
|
||||
|
||||
return curateStash(stash);
|
||||
}
|
||||
|
||||
export async function fetchStashes(domain, itemId, sessionUser) {
|
||||
const stashes = await knex(`stashes_${domain}s`)
|
||||
.select('stashes.*')
|
||||
.where({
|
||||
[`${domain}_id`]: itemId,
|
||||
user_id: sessionUser.id,
|
||||
})
|
||||
.leftJoin('stashes', 'stashes.id', `stashes_${domain}s.stash_id`);
|
||||
|
||||
return stashes.map((stash) => curateStash(stash));
|
||||
}
|
||||
|
||||
export async function createStash(newStash, sessionUser) {
|
||||
if (!sessionUser) {
|
||||
throw new HttpError('You are not authenthicated', 401);
|
||||
}
|
||||
|
||||
try {
|
||||
const stash = await knex('stashes')
|
||||
.insert(curateStashEntry(newStash, sessionUser))
|
||||
.returning('*');
|
||||
|
||||
return curateStash(stash);
|
||||
} catch (error) {
|
||||
if (error.routine === '_bt_check_unique') {
|
||||
throw new HttpError('Stash name should be unique', 409);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateStash(stashId, newStash, sessionUser) {
|
||||
if (!sessionUser) {
|
||||
throw new HttpError('You are not authenthicated', 401);
|
||||
}
|
||||
|
||||
const stash = await knex('stashes')
|
||||
.where({
|
||||
id: stashId,
|
||||
user_id: sessionUser.id,
|
||||
})
|
||||
.update(newStash)
|
||||
.returning('*');
|
||||
|
||||
if (!stash) {
|
||||
throw new HttpError('You are not authorized to modify this stash', 403);
|
||||
}
|
||||
|
||||
return curateStash(stash);
|
||||
}
|
||||
|
||||
export async function removeStash(stashId, sessionUser) {
|
||||
if (!sessionUser) {
|
||||
throw new HttpError('You are not authenthicated', 401);
|
||||
}
|
||||
|
||||
const removed = await knex('stashes')
|
||||
.where({
|
||||
id: stashId,
|
||||
user_id: sessionUser.id,
|
||||
primary: false,
|
||||
})
|
||||
.delete();
|
||||
|
||||
if (removed === 0) {
|
||||
throw new HttpError('Unable to remove this stash', 400);
|
||||
}
|
||||
}
|
||||
|
||||
export async function refreshActorsView() {
|
||||
if (new Date() - lastActorsViewRefresh > config.stashes.viewRefreshCooldown * 60000) {
|
||||
// don't refresh actors view more than once an hour
|
||||
lastActorsViewRefresh = new Date();
|
||||
|
||||
logger.debug('Refreshing actors view');
|
||||
|
||||
return knex.schema.refreshMaterializedView('actors_meta');
|
||||
}
|
||||
|
||||
logger.silly('Skipping actors view refresh');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function stashActor(actorId, stashId, sessionUser) {
|
||||
const stash = await fetchStash(stashId, sessionUser);
|
||||
|
||||
await knex('stashes_actors')
|
||||
.insert({
|
||||
stash_id: stash.id,
|
||||
actor_id: actorId,
|
||||
});
|
||||
|
||||
refreshActorsView();
|
||||
|
||||
return fetchStashes('actor', actorId, sessionUser);
|
||||
}
|
||||
|
||||
export async function stashScene(sceneId, stashId, sessionUser) {
|
||||
const stash = await fetchStash(stashId, sessionUser);
|
||||
|
||||
await knex('stashes_scenes')
|
||||
.insert({
|
||||
stash_id: stash.id,
|
||||
scene_id: sceneId,
|
||||
});
|
||||
|
||||
return fetchStashes('scene', sceneId, sessionUser);
|
||||
}
|
||||
|
||||
export async function stashMovie(movieId, stashId, sessionUser) {
|
||||
const stash = await fetchStash(stashId, sessionUser);
|
||||
|
||||
await knex('stashes_movies')
|
||||
.insert({
|
||||
stash_id: stash.id,
|
||||
movie_id: movieId,
|
||||
});
|
||||
|
||||
return fetchStashes('movie', movieId, sessionUser);
|
||||
}
|
||||
|
||||
export async function unstashActor(actorId, stashId, sessionUser) {
|
||||
await knex
|
||||
.from('stashes_actors AS deletable')
|
||||
.where('deletable.actor_id', actorId)
|
||||
.where('deletable.stash_id', stashId)
|
||||
.whereExists(knex('stashes_actors') // verify user owns this stash, complimentary to row-level security
|
||||
.leftJoin('stashes', 'stashes.id', 'stashes_actors.stash_id')
|
||||
.where('stashes_actors.stash_id', knex.raw('deletable.stash_id'))
|
||||
.where('stashes.user_id', sessionUser.id))
|
||||
.delete();
|
||||
|
||||
refreshActorsView();
|
||||
|
||||
return fetchStashes('actor', actorId, sessionUser);
|
||||
}
|
||||
|
||||
export async function unstashScene(sceneId, stashId, sessionUser) {
|
||||
await knex
|
||||
.from('stashes_scenes AS deletable')
|
||||
.where('deletable.scene_id', sceneId)
|
||||
.where('deletable.stash_id', stashId)
|
||||
.whereExists(knex('stashes_scenes') // verify user owns this stash, complimentary to row-level security
|
||||
.leftJoin('stashes', 'stashes.id', 'stashes_scenes.stash_id')
|
||||
.where('stashes_scenes.stash_id', knex.raw('deletable.stash_id'))
|
||||
.where('stashes.user_id', sessionUser.id))
|
||||
.delete();
|
||||
|
||||
return fetchStashes('scene', sceneId, sessionUser);
|
||||
}
|
||||
|
||||
export async function unstashMovie(movieId, stashId, sessionUser) {
|
||||
await knex
|
||||
.from('stashes_movies AS deletable')
|
||||
.where('deletable.movie_id', movieId)
|
||||
.where('deletable.stash_id', stashId)
|
||||
.whereExists(knex('stashes_movies') // verify user owns this stash, complimentary to row-level security
|
||||
.leftJoin('stashes', 'stashes.id', 'stashes_movies.stash_id')
|
||||
.where('stashes_movies.stash_id', knex.raw('deletable.stash_id'))
|
||||
.where('stashes.user_id', sessionUser.id))
|
||||
.delete();
|
||||
|
||||
return fetchStashes('movie', movieId, sessionUser);
|
||||
}
|
||||
54
src/users.js
54
src/users.js
@@ -1,12 +1,13 @@
|
||||
import knex from './knex.js';
|
||||
// import { curateStash } from './stashes.js';
|
||||
import { knexOwner as knex } from './knex.js';
|
||||
import { curateStash } from './stashes.js';
|
||||
import { HttpError } from './errors.js';
|
||||
|
||||
export function curateUser(user) {
|
||||
export function curateUser(user, assets = {}) {
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const ability = [...(user.role_abilities || []), ...(user.abilities || [])];
|
||||
const curatedStashes = assets.stashes?.filter(Boolean).map((stash) => curateStash(stash)) || [];
|
||||
|
||||
const curatedUser = {
|
||||
id: user.id,
|
||||
@@ -14,39 +15,48 @@ export function curateUser(user) {
|
||||
email: user.email,
|
||||
emailVerified: user.email_verified,
|
||||
identityVerified: user.identity_verified,
|
||||
ability,
|
||||
avatar: `/media/avatars/${user.id}_${user.username}.png`,
|
||||
createdAt: user.created_at,
|
||||
// stashes: user.stashes?.filter(Boolean).map((stash) => curateStash(stash)) || [],
|
||||
stashes: curatedStashes,
|
||||
primaryStash: curatedStashes.find((stash) => stash.primary),
|
||||
};
|
||||
|
||||
return curatedUser;
|
||||
}
|
||||
|
||||
function whereUser(builder, userId, options = {}) {
|
||||
if (typeof userId === 'number') {
|
||||
builder.where('users.id', userId);
|
||||
}
|
||||
|
||||
if (typeof userId === 'string') {
|
||||
builder.where(knex.raw('lower(users.username)'), userId.toLowerCase());
|
||||
|
||||
if (options.email) {
|
||||
builder.orWhere(knex.raw('lower(users.email)'), userId.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchUser(userId, options = {}) {
|
||||
const user = await knex('users')
|
||||
.select(knex.raw('users.*, users_roles.abilities as role_abilities, COALESCE(json_agg(stashes ORDER BY stashes.created_at) FILTER (WHERE stashes.id IS NOT NULL), \'[]\') as stashes'))
|
||||
.modify((builder) => {
|
||||
if (typeof userId === 'number') {
|
||||
builder.where('users.id', userId);
|
||||
}
|
||||
|
||||
if (typeof userId === 'string') {
|
||||
builder.where(knex.raw('lower(users.username)'), userId.toLowerCase());
|
||||
|
||||
if (options.email) {
|
||||
builder.orWhere(knex.raw('lower(users.email)'), userId.toLowerCase());
|
||||
}
|
||||
}
|
||||
})
|
||||
.select(knex.raw('users.*, users_roles.abilities as role_abilities'))
|
||||
.modify((builder) => whereUser(builder, userId, options))
|
||||
.leftJoin('users_roles', 'users_roles.role', 'users.role')
|
||||
.leftJoin('stashes', 'stashes.user_id', 'users.id')
|
||||
.groupBy('users.id', 'users_roles.role')
|
||||
.first();
|
||||
|
||||
if (!user) {
|
||||
throw HttpError(`User '${userId}' not found`, 404);
|
||||
}
|
||||
|
||||
if (options.raw) {
|
||||
return user;
|
||||
}
|
||||
|
||||
return curateUser(user);
|
||||
const stashes = await knex('stashes')
|
||||
.where('user_id', user.id)
|
||||
.leftJoin('stashes_meta', 'stashes_meta.stash_id', 'stashes.id');
|
||||
|
||||
return curateUser(user, { stashes });
|
||||
}
|
||||
|
||||
75
src/utils/slugify.js
Executable file
75
src/utils/slugify.js
Executable file
@@ -0,0 +1,75 @@
|
||||
const substitutes = {
|
||||
à: 'a',
|
||||
á: 'a',
|
||||
ä: 'a',
|
||||
å: 'a',
|
||||
ã: 'a',
|
||||
æ: 'ae',
|
||||
ç: 'c',
|
||||
è: 'e',
|
||||
é: 'e',
|
||||
ë: 'e',
|
||||
ẽ: 'e',
|
||||
ì: 'i',
|
||||
í: 'i',
|
||||
ï: 'i',
|
||||
ĩ: 'i',
|
||||
ǹ: 'n',
|
||||
ń: 'n',
|
||||
ñ: 'n',
|
||||
ò: 'o',
|
||||
ó: 'o',
|
||||
ö: 'o',
|
||||
õ: 'o',
|
||||
ø: 'o',
|
||||
œ: 'oe',
|
||||
ß: 'ss',
|
||||
ù: 'u',
|
||||
ú: 'u',
|
||||
ü: 'u',
|
||||
ũ: 'u',
|
||||
ỳ: 'y',
|
||||
ý: 'y',
|
||||
ÿ: 'y',
|
||||
ỹ: 'y',
|
||||
};
|
||||
|
||||
export default function slugify(strings, delimiter = '-', {
|
||||
encode = false,
|
||||
removeAccents = true,
|
||||
removePunctuation = false,
|
||||
limit = 1000,
|
||||
} = {}) {
|
||||
if (!strings || (typeof strings !== 'string' && !Array.isArray(strings))) {
|
||||
return strings;
|
||||
}
|
||||
|
||||
const slugComponents = []
|
||||
.concat(strings)
|
||||
.filter(Boolean)
|
||||
.flatMap((string) => string
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(removePunctuation && /[.,:;'"_-]/g, '')
|
||||
.match(/[A-Za-zÀ-ÖØ-öø-ÿ0-9]+/g));
|
||||
|
||||
if (!slugComponents) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const slug = slugComponents.reduce((acc, component, index) => {
|
||||
const accSlug = `${acc}${index > 0 ? delimiter : ''}${component}`;
|
||||
|
||||
if (accSlug.length < limit) {
|
||||
if (removeAccents) {
|
||||
return accSlug.replace(/[à-ÿ]/g, (match) => substitutes[match] || '');
|
||||
}
|
||||
|
||||
return accSlug;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, '');
|
||||
|
||||
return encode ? encodeURI(slug) : slug;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { login, signup } from '../auth.js';
|
||||
import { fetchUser } from '../users.js';
|
||||
|
||||
export async function setUserApi(req, res, next) {
|
||||
if (req.session.user) {
|
||||
@@ -27,17 +26,6 @@ export async function logoutApi(req, res) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchMeApi(req, res) {
|
||||
if (req.session.user) {
|
||||
req.session.user = await fetchUser(req.session.user.id, false, req.session.user);
|
||||
|
||||
res.send(req.session.user);
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(401).send();
|
||||
}
|
||||
|
||||
export async function signupApi(req, res) {
|
||||
const user = await signup(req.body);
|
||||
|
||||
|
||||
@@ -37,6 +37,18 @@ import {
|
||||
signupApi,
|
||||
} from './auth.js';
|
||||
|
||||
import {
|
||||
createStashApi,
|
||||
removeStashApi,
|
||||
stashActorApi,
|
||||
stashSceneApi,
|
||||
stashMovieApi,
|
||||
unstashActorApi,
|
||||
unstashSceneApi,
|
||||
unstashMovieApi,
|
||||
updateStashApi,
|
||||
} from './stashes.js';
|
||||
|
||||
import initLogger from '../logger.js';
|
||||
|
||||
const logger = initLogger();
|
||||
@@ -97,6 +109,19 @@ export default async function initServer() {
|
||||
// USERS
|
||||
router.post('/api/users', signupApi);
|
||||
|
||||
// STASHES
|
||||
router.post('/api/stashes', createStashApi);
|
||||
router.patch('/api/stashes/:stashId', updateStashApi);
|
||||
router.delete('/api/stashes/:stashId', removeStashApi);
|
||||
|
||||
router.post('/api/stashes/:stashId/actors', stashActorApi);
|
||||
router.post('/api/stashes/:stashId/scenes', stashSceneApi);
|
||||
router.post('/api/stashes/:stashId/movies', stashMovieApi);
|
||||
|
||||
router.delete('/api/stashes/:stashId/actors/:actorId', unstashActorApi);
|
||||
router.delete('/api/stashes/:stashId/scenes/:sceneId', unstashSceneApi);
|
||||
router.delete('/api/stashes/:stashId/movies/:movieId', unstashMovieApi);
|
||||
|
||||
// SCENES
|
||||
router.get('/api/scenes', fetchScenesApi);
|
||||
|
||||
|
||||
65
src/web/stashes.js
Executable file
65
src/web/stashes.js
Executable file
@@ -0,0 +1,65 @@
|
||||
import {
|
||||
createStash,
|
||||
removeStash,
|
||||
stashActor,
|
||||
stashScene,
|
||||
stashMovie,
|
||||
unstashActor,
|
||||
unstashScene,
|
||||
unstashMovie,
|
||||
updateStash,
|
||||
} from '../stashes.js';
|
||||
|
||||
export async function createStashApi(req, res) {
|
||||
const stash = await createStash(req.body, req.session.user);
|
||||
|
||||
res.send(stash);
|
||||
}
|
||||
|
||||
export async function updateStashApi(req, res) {
|
||||
const stash = await updateStash(req.params.stashId, req.body, req.session.user);
|
||||
|
||||
res.send(stash);
|
||||
}
|
||||
|
||||
export async function removeStashApi(req, res) {
|
||||
await removeStash(req.params.stashId, req.session.user);
|
||||
|
||||
res.status(204).send();
|
||||
}
|
||||
|
||||
export async function stashActorApi(req, res) {
|
||||
const stashes = await stashActor(req.body.actorId, req.params.stashId, req.user);
|
||||
|
||||
res.send(stashes);
|
||||
}
|
||||
|
||||
export async function stashSceneApi(req, res) {
|
||||
const stashes = await stashScene(req.body.sceneId, req.params.stashId, req.user);
|
||||
|
||||
res.send(stashes);
|
||||
}
|
||||
|
||||
export async function stashMovieApi(req, res) {
|
||||
const stashes = await stashMovie(req.body.movieId, req.params.stashId, req.user);
|
||||
|
||||
res.send(stashes);
|
||||
}
|
||||
|
||||
export async function unstashActorApi(req, res) {
|
||||
const stashes = await unstashActor(req.params.actorId, req.params.stashId, req.user);
|
||||
|
||||
res.send(stashes);
|
||||
}
|
||||
|
||||
export async function unstashSceneApi(req, res) {
|
||||
const stashes = await unstashScene(req.params.sceneId, req.params.stashId, req.user);
|
||||
|
||||
res.send(stashes);
|
||||
}
|
||||
|
||||
export async function unstashMovieApi(req, res) {
|
||||
const stashes = await unstashMovie(req.params.movieId, req.params.stashId, req.user);
|
||||
|
||||
res.send(stashes);
|
||||
}
|
||||
Reference in New Issue
Block a user