mirror of
https://github.com/seerr-team/seerr.git
synced 2026-06-15 11:59:11 -04:00
refactor(quickconnect): implement zod validation for quick connect secret
This commit is contained in:
@@ -18,9 +18,18 @@ import axios from 'axios';
|
||||
import { Router } from 'express';
|
||||
import net from 'net';
|
||||
import validator from 'validator';
|
||||
import { z } from 'zod';
|
||||
|
||||
const authRoutes = Router();
|
||||
|
||||
export const quickConnectSecret = z.object({
|
||||
secret: z
|
||||
.string()
|
||||
.min(8)
|
||||
.max(128)
|
||||
.regex(/^[A-Fa-f0-9]+$/),
|
||||
});
|
||||
|
||||
authRoutes.get('/me', isAuthenticated(), async (req, res) => {
|
||||
const userRepository = getRepository(User);
|
||||
if (!req.user) {
|
||||
@@ -621,21 +630,16 @@ authRoutes.post('/jellyfin/quickconnect/initiate', async (req, res, next) => {
|
||||
});
|
||||
|
||||
authRoutes.get('/jellyfin/quickconnect/check', async (req, res, next) => {
|
||||
const secret = req.query.secret as string;
|
||||
|
||||
if (
|
||||
!secret ||
|
||||
typeof secret !== 'string' ||
|
||||
secret.length < 8 ||
|
||||
secret.length > 128 ||
|
||||
!/^[A-Fa-f0-9]+$/.test(secret)
|
||||
) {
|
||||
const result = quickConnectSecret.safeParse(req.query);
|
||||
if (!result.success) {
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Invalid secret format',
|
||||
});
|
||||
}
|
||||
|
||||
const { secret } = result.data;
|
||||
|
||||
try {
|
||||
const hostname = getHostname();
|
||||
const jellyfinServer = new JellyfinAPI(
|
||||
@@ -660,21 +664,16 @@ authRoutes.post(
|
||||
async (req, res, next) => {
|
||||
const settings = getSettings();
|
||||
const userRepository = getRepository(User);
|
||||
const body = req.body as { secret?: string };
|
||||
|
||||
if (
|
||||
!body.secret ||
|
||||
typeof body.secret !== 'string' ||
|
||||
body.secret.length < 8 ||
|
||||
body.secret.length > 128 ||
|
||||
!/^[A-Fa-f0-9]+$/.test(body.secret)
|
||||
) {
|
||||
const result = quickConnectSecret.safeParse(req.body);
|
||||
if (!result.success) {
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Secret required',
|
||||
});
|
||||
}
|
||||
|
||||
const { secret } = result.data;
|
||||
|
||||
if (
|
||||
settings.main.mediaServerType === MediaServerType.NOT_CONFIGURED ||
|
||||
!(await userRepository.count())
|
||||
@@ -693,9 +692,7 @@ authRoutes.post(
|
||||
undefined
|
||||
);
|
||||
|
||||
const account = await jellyfinServer.authenticateQuickConnect(
|
||||
body.secret
|
||||
);
|
||||
const account = await jellyfinServer.authenticateQuickConnect(secret);
|
||||
|
||||
let user = await userRepository.findOne({
|
||||
where: { jellyfinUserId: account.User.Id },
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Permission } from '@server/lib/permissions';
|
||||
import { getSettings } from '@server/lib/settings';
|
||||
import logger from '@server/logger';
|
||||
import { isAuthenticated } from '@server/middleware/auth';
|
||||
import { quickConnectSecret } from '@server/routes/auth';
|
||||
import { ApiError } from '@server/types/error';
|
||||
import { getHostname } from '@server/utils/getHostname';
|
||||
import {
|
||||
@@ -525,17 +526,13 @@ userSettingsRoutes.post<{ secret: string }>(
|
||||
return res.status(401).json({ code: ApiErrorCode.Unauthorized });
|
||||
}
|
||||
|
||||
const secret = req.body.secret;
|
||||
if (
|
||||
!secret ||
|
||||
typeof secret !== 'string' ||
|
||||
secret.length < 8 ||
|
||||
secret.length > 128 ||
|
||||
!/^[A-Fa-f0-9]+$/.test(secret)
|
||||
) {
|
||||
const result = quickConnectSecret.safeParse(req.body);
|
||||
if (!result.success) {
|
||||
return res.status(400).json({ message: 'Invalid secret format' });
|
||||
}
|
||||
|
||||
const { secret } = result.data;
|
||||
|
||||
if (
|
||||
settings.main.mediaServerType !== MediaServerType.JELLYFIN &&
|
||||
settings.main.mediaServerType !== MediaServerType.EMBY
|
||||
|
||||
Reference in New Issue
Block a user