Upgraded dependencies, bumped to Node 24.
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import Router from 'express-promise-router';
|
||||
import { Router } from 'express';
|
||||
import omit from 'object.omit';
|
||||
|
||||
import {
|
||||
createActor,
|
||||
createActorRevision,
|
||||
fetchActorRevisions,
|
||||
fetchActors,
|
||||
fetchActorsById,
|
||||
createActor,
|
||||
mergeActors,
|
||||
fetchActorRevisions,
|
||||
createActorRevision,
|
||||
reviewActorRevision,
|
||||
} from '../actors.js';
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import Router from 'express-promise-router';
|
||||
import { Router } from 'express';
|
||||
|
||||
import {
|
||||
fetchAlerts,
|
||||
createAlert,
|
||||
removeAlert,
|
||||
fetchAlerts,
|
||||
fetchNotifications,
|
||||
updateNotifications,
|
||||
removeAlert,
|
||||
updateNotification,
|
||||
updateNotifications,
|
||||
} from '../alerts.js';
|
||||
|
||||
// actors and actorIds, stashes and stashIds are aliases for consistency
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
import { stringify } from '@brillout/json-serializer/stringify'; /* eslint-disable-line import/extensions */
|
||||
import { stringify } from '@brillout/json-serializer/stringify';
|
||||
import IPCIDR from 'ip-cidr';
|
||||
import argv from '../argv.js';
|
||||
|
||||
import {
|
||||
login,
|
||||
signup,
|
||||
fetchUserKeys,
|
||||
createKey,
|
||||
removeUserKey,
|
||||
fetchUserKeys,
|
||||
flushUserKeys,
|
||||
login,
|
||||
removeUserKey,
|
||||
signup,
|
||||
} from '../auth.js';
|
||||
|
||||
import { fetchUser } from '../users.js';
|
||||
@@ -111,4 +110,3 @@ export async function flushUserKeysApi(req, res) {
|
||||
|
||||
res.status(204).send();
|
||||
}
|
||||
/* eslint-enable no-param-reassign */
|
||||
|
||||
@@ -4,26 +4,26 @@ export default function consentHandler(req, res, next) {
|
||||
if (Object.hasOwn(req.query, 'lgbt')) {
|
||||
const lgbtFilters = Array.from(new Set([...(req.tagFilter || []).filter((tag) => !['gay', 'bisexual', 'transsexual'].includes(tag)), 'extreme-insertion']));
|
||||
|
||||
req.tagFilter = lgbtFilters; // eslint-disable-line no-param-reassign
|
||||
req.tagFilter = lgbtFilters;
|
||||
res.cookie('tags', JSON.stringify(lgbtFilters));
|
||||
}
|
||||
|
||||
if (Object.hasOwn(req.query, 'straight')) {
|
||||
const straightFilters = Array.from(new Set([...(req.tagFilter || []), 'gay', 'bisexual', 'transsexual', 'extreme-insertion']));
|
||||
|
||||
req.tagFilter = straightFilters; // eslint-disable-line no-param-reassign
|
||||
req.tagFilter = straightFilters;
|
||||
res.cookie('tags', JSON.stringify(straightFilters));
|
||||
}
|
||||
|
||||
if (Object.hasOwn(req.query, 'consent')) {
|
||||
req.session.hasConsent = true; // eslint-disable-line no-param-reassign
|
||||
req.session.hasConsent = true;
|
||||
res.redirect(redirect || req.path);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!req.path.includes('/consent') && !req.session?.hasConsent) {
|
||||
res.redirect(`/consent?redirect=${req.originalUrl === '/' ? '' : encodeURIComponent(req.originalUrl) }`);
|
||||
res.redirect(`/consent?redirect=${req.originalUrl === '/' ? '' : encodeURIComponent(req.originalUrl)}`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { parseResolveInfo } from 'graphql-parse-resolve-info';
|
||||
|
||||
import { getIdsBySlug } from '../cache.js';
|
||||
|
||||
import {
|
||||
fetchEntities,
|
||||
fetchEntitiesById,
|
||||
} from '../entities.js';
|
||||
|
||||
import { getIdsBySlug } from '../cache.js';
|
||||
|
||||
export async function fetchEntitiesApi(req, res) {
|
||||
const entities = await fetchEntities(req.query);
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import config from 'config';
|
||||
import { format } from 'date-fns';
|
||||
|
||||
import {
|
||||
graphql,
|
||||
buildSchema,
|
||||
graphql,
|
||||
GraphQLScalarType,
|
||||
} from 'graphql';
|
||||
|
||||
@@ -12,56 +12,56 @@ import {
|
||||
JSONResolver,
|
||||
} from 'graphql-scalars';
|
||||
|
||||
import {
|
||||
scenesSchema,
|
||||
fetchScenesGraphql,
|
||||
fetchScenesByIdGraphql,
|
||||
} from './scenes.js';
|
||||
|
||||
import {
|
||||
moviesSchema,
|
||||
fetchMoviesGraphql,
|
||||
fetchMoviesByIdGraphql,
|
||||
} from './movies.js';
|
||||
|
||||
import {
|
||||
entitiesSchema,
|
||||
fetchEntitiesGraphql,
|
||||
fetchEntitiesByIdGraphql,
|
||||
} from './entities.js';
|
||||
import { verifyKey } from '../auth.js';
|
||||
|
||||
import {
|
||||
actorsSchema,
|
||||
fetchActorsGraphql,
|
||||
fetchActorsByIdGraphql,
|
||||
fetchActorsGraphql,
|
||||
} from './actors.js';
|
||||
|
||||
import {
|
||||
stashesSchema,
|
||||
fetchUserStashesGraphql,
|
||||
fetchStashGraphql,
|
||||
createStashGraphql,
|
||||
updateStashGraphql,
|
||||
removeStashGraphql,
|
||||
stashSceneGraphql,
|
||||
unstashSceneGraphql,
|
||||
stashActorGraphql,
|
||||
unstashActorGraphql,
|
||||
stashMovieGraphql,
|
||||
unstashMovieGraphql,
|
||||
} from './stashes.js';
|
||||
|
||||
import {
|
||||
alertsSchema,
|
||||
fetchAlertsGraphql,
|
||||
createAlertGraphql,
|
||||
removeAlertGraphql,
|
||||
fetchAlertsGraphql,
|
||||
fetchNotificationsGraphql,
|
||||
removeAlertGraphql,
|
||||
updateNotificationGraphql,
|
||||
updateNotificationsGraphql,
|
||||
} from './alerts.js';
|
||||
|
||||
import { verifyKey } from '../auth.js';
|
||||
import {
|
||||
entitiesSchema,
|
||||
fetchEntitiesByIdGraphql,
|
||||
fetchEntitiesGraphql,
|
||||
} from './entities.js';
|
||||
|
||||
import {
|
||||
fetchMoviesByIdGraphql,
|
||||
fetchMoviesGraphql,
|
||||
moviesSchema,
|
||||
} from './movies.js';
|
||||
|
||||
import {
|
||||
fetchScenesByIdGraphql,
|
||||
fetchScenesGraphql,
|
||||
scenesSchema,
|
||||
} from './scenes.js';
|
||||
|
||||
import {
|
||||
createStashGraphql,
|
||||
fetchStashGraphql,
|
||||
fetchUserStashesGraphql,
|
||||
removeStashGraphql,
|
||||
stashActorGraphql,
|
||||
stashesSchema,
|
||||
stashMovieGraphql,
|
||||
stashSceneGraphql,
|
||||
unstashActorGraphql,
|
||||
unstashMovieGraphql,
|
||||
unstashSceneGraphql,
|
||||
updateStashGraphql,
|
||||
} from './stashes.js';
|
||||
|
||||
const schema = buildSchema(`
|
||||
type Query {
|
||||
@@ -114,7 +114,7 @@ export async function graphqlApi(req, res) {
|
||||
|
||||
await verifyKey(req.headers['api-user'], req.headers['api-key'], req);
|
||||
|
||||
req.user = { // eslint-disable-line no-param-reassign
|
||||
req.user = {
|
||||
id: Number(req.headers['api-user']),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import config from 'config';
|
||||
import { renderPage } from 'vike/server'; // eslint-disable-line import/extensions
|
||||
import { renderPage } from 'vike/server';
|
||||
|
||||
import { socials } from '../../common/actors.mjs';
|
||||
import { fetchUnseenNotificationsCount } from '../alerts.js';
|
||||
import { fetchUserStashes } from '../stashes.js';
|
||||
import { fetchUserTemplates } from '../users.js';
|
||||
import { fetchUnseenNotificationsCount } from '../alerts.js';
|
||||
import { socials } from '../../common/actors.mjs'; // eslint-disable-line import/namespace
|
||||
|
||||
export default async function mainHandler(req, res, next) {
|
||||
const [stashes, templates, unseenNotifications] = req.user ? await Promise.all([
|
||||
fetchUserStashes(req.user.id, req.user),
|
||||
fetchUserTemplates(req.user),
|
||||
fetchUnseenNotificationsCount(req.user),
|
||||
]) : [];
|
||||
const [stashes, templates, unseenNotifications] = req.user
|
||||
? await Promise.all([
|
||||
fetchUserStashes(req.user.id, req.user),
|
||||
fetchUserTemplates(req.user),
|
||||
fetchUnseenNotificationsCount(req.user),
|
||||
])
|
||||
: [];
|
||||
|
||||
const pageContextInit = {
|
||||
urlOriginal: req.originalUrl,
|
||||
@@ -27,12 +29,14 @@ export default async function mainHandler(req, res, next) {
|
||||
abilities: req.user.abilities,
|
||||
avatar: req.user.avatar,
|
||||
},
|
||||
assets: req.user ? {
|
||||
stashes,
|
||||
primaryStash: stashes.find((stash) => stash.isPrimary),
|
||||
templates,
|
||||
unseenNotifications,
|
||||
} : null,
|
||||
assets: req.user
|
||||
? {
|
||||
stashes,
|
||||
primaryStash: stashes.find((stash) => stash.isPrimary),
|
||||
templates,
|
||||
unseenNotifications,
|
||||
}
|
||||
: null,
|
||||
env: {
|
||||
theme: req.cookies.theme || req.headers['sec-ch-prefers-color-scheme'] || 'light',
|
||||
scenesView: req.cookies.scenesView || 'list',
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { stringify } from '@brillout/json-serializer/stringify'; /* eslint-disable-line import/extensions */
|
||||
import { stringify } from '@brillout/json-serializer/stringify';
|
||||
|
||||
import { fetchMovies, fetchMoviesById } from '../movies.js';
|
||||
import { fetchStashByUsernameAndSlug } from '../stashes.js';
|
||||
import { parseActorIdentifier } from '../query.js';
|
||||
import { getIdsBySlug } from '../cache.js';
|
||||
import slugify from '../../utils/slugify.js';
|
||||
import promiseProps from '../../utils/promise-props.js';
|
||||
import slugify from '../../utils/slugify.js';
|
||||
import { getIdsBySlug } from '../cache.js';
|
||||
import { HttpError } from '../errors.js';
|
||||
import { fetchMovies, fetchMoviesById } from '../movies.js';
|
||||
import { parseActorIdentifier } from '../query.js';
|
||||
import { fetchStashByUsernameAndSlug } from '../stashes.js';
|
||||
|
||||
export async function curateMoviesQuery(query) {
|
||||
return {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import config from 'config';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
import { Reader } from '@maxmind/geoip2-node';
|
||||
import config from 'config';
|
||||
|
||||
import initLogger from '../logger.js';
|
||||
|
||||
@@ -69,7 +69,8 @@ export default async function initRestrictionHandler() {
|
||||
|
||||
req.restriction = restriction;
|
||||
req.country = country;
|
||||
} catch (error) {
|
||||
}
|
||||
catch (error) {
|
||||
logger.error(`Failed Maxmind IP lookup for ${req.ip}: ${error.message}`);
|
||||
|
||||
req.session.restrictionIp = req.userIp;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// https://stackoverflow.com/questions/46745014/alternative-for-dirname-in-node-when-using-the-experimental-modules-flag/50052194#50052194
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const root = `${__dirname}/..`;
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import Router from 'express-promise-router';
|
||||
import { stringify } from '@brillout/json-serializer/stringify'; /* eslint-disable-line import/extensions */
|
||||
import { stringify } from '@brillout/json-serializer/stringify';
|
||||
import { Router } from 'express';
|
||||
|
||||
import promiseProps from '../../utils/promise-props.js';
|
||||
|
||||
import slugify from '../../utils/slugify.js';
|
||||
|
||||
import { getIdsBySlug } from '../cache.js';
|
||||
import { HttpError } from '../errors.js';
|
||||
import { parseActorIdentifier } from '../query.js';
|
||||
import {
|
||||
createSceneRevision,
|
||||
fetchSceneRevisions,
|
||||
fetchScenes,
|
||||
fetchScenesById,
|
||||
fetchSceneRevisions,
|
||||
createSceneRevision,
|
||||
reviewSceneRevision,
|
||||
} from '../scenes.js';
|
||||
|
||||
import { fetchStashByUsernameAndSlug } from '../stashes.js';
|
||||
|
||||
import { parseActorIdentifier } from '../query.js';
|
||||
import { getIdsBySlug } from '../cache.js';
|
||||
import slugify from '../../utils/slugify.js';
|
||||
import { HttpError } from '../errors.js';
|
||||
import promiseProps from '../../utils/promise-props.js';
|
||||
|
||||
export async function curateScenesQuery(query) {
|
||||
const splitYears = query.years?.split(',') || [];
|
||||
const splitTags = query.tags?.split(',') || [];
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
import config from 'config';
|
||||
import path from 'path';
|
||||
import express from 'express';
|
||||
import boolParser from 'express-query-boolean';
|
||||
import Router from 'express-promise-router';
|
||||
import session from 'express-session';
|
||||
import RedisStore from 'connect-redis';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import compression from 'compression';
|
||||
import cookie from 'cookie';
|
||||
|
||||
import redis from '../redis.js';
|
||||
|
||||
import errorHandler from './error.js';
|
||||
import consentHandler from './consent.js';
|
||||
import initRestrictionHandler from './restrictions.js';
|
||||
|
||||
import { scenesRouter } from './scenes.js';
|
||||
import { actorsRouter } from './actors.js';
|
||||
import { syncRouter } from './sync.js';
|
||||
|
||||
import { fetchMoviesApi } from './movies.js';
|
||||
import { fetchEntitiesApi } from './entities.js';
|
||||
import { fetchTagsApi } from './tags.js';
|
||||
import config from 'config';
|
||||
import { RedisStore } from 'connect-redis';
|
||||
import { parseCookie } from 'cookie';
|
||||
import express, { Router } from 'express';
|
||||
import session from 'express-session';
|
||||
|
||||
import { verifyKey } from '../auth.js';
|
||||
import initLogger from '../logger.js';
|
||||
|
||||
import redis from '../redis.js';
|
||||
import queryBoolean from '../utils/query-boolean.js';
|
||||
import { actorsRouter } from './actors.js';
|
||||
|
||||
import { router as alertsRouter } from './alerts.js';
|
||||
import {
|
||||
createKeyApi,
|
||||
fetchUserKeysApi,
|
||||
flushUserKeysApi,
|
||||
loginApi,
|
||||
logoutApi,
|
||||
removeUserKeyApi,
|
||||
setUserApi,
|
||||
signupApi,
|
||||
} from './auth.js';
|
||||
import consentHandler from './consent.js';
|
||||
|
||||
import { fetchEntitiesApi } from './entities.js';
|
||||
import errorHandler from './error.js';
|
||||
import { graphqlApi } from './graphql.js';
|
||||
|
||||
import mainHandler from './main.js';
|
||||
import { fetchMoviesApi } from './movies.js';
|
||||
|
||||
import {
|
||||
setUserApi,
|
||||
loginApi,
|
||||
logoutApi,
|
||||
signupApi,
|
||||
fetchUserKeysApi,
|
||||
createKeyApi,
|
||||
removeUserKeyApi,
|
||||
flushUserKeysApi,
|
||||
} from './auth.js';
|
||||
import initRestrictionHandler from './restrictions.js';
|
||||
|
||||
import { scenesRouter } from './scenes.js';
|
||||
|
||||
import { router as userRouter } from './users.js';
|
||||
import { router as stashesRouter } from './stashes.js';
|
||||
import { router as alertsRouter } from './alerts.js';
|
||||
|
||||
import { syncRouter } from './sync.js';
|
||||
import { initCachesApi } from './system.js';
|
||||
|
||||
import initLogger from '../logger.js';
|
||||
import { fetchTagsApi } from './tags.js';
|
||||
|
||||
import { router as userRouter } from './users.js';
|
||||
|
||||
const logger = initLogger();
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
@@ -57,8 +57,11 @@ export default async function initServer() {
|
||||
app.use(compression());
|
||||
app.disable('x-powered-by');
|
||||
app.set('view engine', 'ejs');
|
||||
// Express 5 defaults to the 'simple' query parser (Node's querystring) instead of 'extended'
|
||||
// (qs), which drops support for the bracket/nested query syntax the app relies on.
|
||||
app.set('query parser', 'extended');
|
||||
|
||||
router.use(boolParser());
|
||||
router.use(queryBoolean());
|
||||
|
||||
router.use('/', express.static('public'));
|
||||
router.use('/', express.static('static'));
|
||||
@@ -66,12 +69,10 @@ export default async function initServer() {
|
||||
|
||||
router.use((req, _res, next) => {
|
||||
if (req.headers.cookie) {
|
||||
const cookies = cookie.parse(req.headers.cookie);
|
||||
const cookies = parseCookie(req.headers.cookie);
|
||||
|
||||
/* eslint-disable no-param-reassign */
|
||||
req.cookies = cookies;
|
||||
req.tagFilter = cookies.tags ? JSON.parse(cookies.tags) : [];
|
||||
/* eslint-enable no-param-reassign */
|
||||
}
|
||||
|
||||
next();
|
||||
@@ -99,7 +100,8 @@ export default async function initServer() {
|
||||
// (In dev, Vite's middleware serves our static assets.)
|
||||
const sirv = (await import('sirv')).default;
|
||||
router.use(sirv('dist/client'));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// We instantiate Vite's development server and integrate its middleware to our server.
|
||||
// ⚠️ We instantiate it only in development. (It isn't needed in production and it
|
||||
// would unnecessarily bloat our production server.)
|
||||
@@ -121,7 +123,7 @@ export default async function initServer() {
|
||||
res.sendFile(path.join(import.meta.dirname, '../../assets/consent.html'));
|
||||
});
|
||||
|
||||
router.use('/api/*', async (req, _res, next) => {
|
||||
router.use('/api/{*splat}', async (req, _res, next) => {
|
||||
if (req.headers['api-user']) {
|
||||
req.user = await verifyKey(req.headers['api-user'], req.headers['api-key'], req);
|
||||
}
|
||||
@@ -167,16 +169,14 @@ export default async function initServer() {
|
||||
router.use(consentHandler);
|
||||
|
||||
router.use((_req, res, next) => {
|
||||
/* eslint-disable no-param-reassign */
|
||||
res.set('Accept-CH', 'Sec-CH-Prefers-Color-Scheme');
|
||||
res.set('Vary', 'Sec-CH-Prefers-Color-Scheme');
|
||||
res.set('Critical-CH', 'Sec-CH-Prefers-Color-Scheme');
|
||||
/* eslint-enable no-param-reassign */
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
router.get('*', mainHandler);
|
||||
router.get('/{*splat}', mainHandler);
|
||||
|
||||
router.use(errorHandler);
|
||||
app.use(router);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import Router from 'express-promise-router';
|
||||
import { Router } from 'express';
|
||||
|
||||
import {
|
||||
fetchUserStashes,
|
||||
createStash,
|
||||
fetchStashByUsernameAndSlug,
|
||||
fetchUserStashes,
|
||||
removeStash,
|
||||
stashActor,
|
||||
stashScene,
|
||||
stashMovie,
|
||||
stashScene,
|
||||
unstashActor,
|
||||
unstashScene,
|
||||
unstashMovie,
|
||||
unstashScene,
|
||||
updateStash,
|
||||
fetchStashByUsernameAndSlug,
|
||||
} from '../stashes.js';
|
||||
|
||||
export const stashesSchema = `
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import Router from 'express-promise-router';
|
||||
|
||||
import {
|
||||
syncScenes,
|
||||
syncMovies,
|
||||
syncActors,
|
||||
syncStashes,
|
||||
syncQueue,
|
||||
} from '../sync.js';
|
||||
import { Router } from 'express';
|
||||
|
||||
import verifyAbility from '../../utils/verify-ability.js';
|
||||
|
||||
import {
|
||||
syncActors,
|
||||
syncMovies,
|
||||
syncQueue,
|
||||
syncScenes,
|
||||
syncStashes,
|
||||
} from '../sync.js';
|
||||
|
||||
export const syncRouter = Router();
|
||||
|
||||
async function syncScenesApi(req, res) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { HttpError } from '../errors.js';
|
||||
import { initCaches } from '../cache.js';
|
||||
import { HttpError } from '../errors.js';
|
||||
|
||||
export async function initCachesApi(req, res) {
|
||||
if (req.user?.role !== 'admin') {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import Router from 'express-promise-router';
|
||||
import { stringify } from '@brillout/json-serializer/stringify'; /* eslint-disable-line import/extensions */
|
||||
import { stringify } from '@brillout/json-serializer/stringify';
|
||||
import { Router } from 'express';
|
||||
|
||||
import {
|
||||
createBan,
|
||||
createTemplate,
|
||||
fetchUser,
|
||||
fetchUserTemplates,
|
||||
createTemplate,
|
||||
removeTemplate,
|
||||
createBan,
|
||||
} from '../users.js';
|
||||
|
||||
async function fetchUserApi(req, res) {
|
||||
|
||||
Reference in New Issue
Block a user