تازه ها

در بخش تازه‌ها , می‌توانید جدیدترین فیلم‌ها و سریال‌های منتشرشده را با دوبله فارسی و زیرنویس اختصاصی مشاهده کنید. این دسته‌بندی به‌صورت روزانه به‌روزرسانی می‌شود تا همیشه به تازه‌ترین آثار سینما و تلویزیون دسترسی داشته باشید. اگر به‌دنبال فیلم‌ها و سریال‌های جدید و داغ روز هستید، اینجا بهترین نقطه شروع شماست.

logo دریافت اپلیکیشن سانتروفیلم
import { NextRequest, NextResponse } from 'next/server'; const AUTH_COOKIE_NAME = 'auth_token'; const LANDING_URL = 'https://app.santroofilm.ir/'; const AUTH_TOKEN_SECRET = process.env.AUTH_TOKEN_SECRET ?? ''; const PUBLIC_FILE_EXTENSIONS = new Set([ 'css', 'js', 'png', 'jpg', 'jpeg', 'svg', 'gif', 'webp', 'ico', 'woff', 'woff2', 'ttf', ]); const PUBLIC_PATHS = new Set([ '/favicon.ico', '/robots.txt', '/manifest.json', '/sitemap.xml', ]); export const config = { matcher: [ '/((?!_next/|api/auth/|favicon.ico|robots.txt|manifest.json|sitemap.xml|.*\\.(?:css|js|png|jpg|jpeg|svg|gif|webp|ico|woff|woff2|ttf)$).*)', ], }; export async function middleware(request: NextRequest): Promise { const { pathname, search } = request.nextUrl; if (isPublicRequest(pathname)) { return NextResponse.next(); } const isValidSession = await hasValidAuthToken(request); if (isValidSession) { return NextResponse.next(); } const redirectUrl = new URL(LANDING_URL); const returnPath = `${pathname}${search}`; if (returnPath !== '/') { redirectUrl.searchParams.set('return', returnPath); } return NextResponse.redirect(redirectUrl); } function isPublicRequest(pathname: string): boolean { if (pathname === '/auth' || pathname.startsWith('/auth/')) { return true; } if (pathname.startsWith('/api/auth/')) { return true; } if (pathname.startsWith('/_next/')) { return true; } if (PUBLIC_PATHS.has(pathname)) { return true; } return isStaticAsset(pathname); } function isStaticAsset(pathname: string): boolean { const lastSegment = pathname.split('/').pop(); if (!lastSegment || !lastSegment.includes('.')) { return false; } const extension = lastSegment.split('.').pop()?.toLowerCase(); return Boolean(extension && PUBLIC_FILE_EXTENSIONS.has(extension)); } async function hasValidAuthToken(request: NextRequest): Promise { const token = request.cookies.get(AUTH_COOKIE_NAME)?.value; if (!token) { return false; } return verifyJwtHS256(token); } async function verifyJwtHS256(token: string): Promise { if (!AUTH_TOKEN_SECRET) { return false; } const parts = token.split('.'); if (parts.length !== 3) { return false; } const [encodedHeader, encodedPayload, encodedSignature] = parts; try { const header = JSON.parse(base64UrlDecodeToString(encodedHeader)) as { alg?: string; typ?: string; }; if (header.alg !== 'HS256') { return false; } const payload = JSON.parse(base64UrlDecodeToString(encodedPayload)) as { exp?: number; nbf?: number; iat?: number; iss?: string; aud?: string | string[]; sub?: string; }; if (!payload.sub) { return false; } const now = Math.floor(Date.now() / 1000); const clockToleranceSeconds = 30; if (typeof payload.exp !== 'number' || payload.exp <= now - clockToleranceSeconds) { return false; } if (typeof payload.nbf === 'number' && payload.nbf > now + clockToleranceSeconds) { return false; } if (typeof payload.iat === 'number' && payload.iat > now + clockToleranceSeconds) { return false; } const expectedSignature = await signHS256(`${encodedHeader}.${encodedPayload}`, AUTH_TOKEN_SECRET); return timingSafeEqual(encodedSignature, expectedSignature); } catch { return false; } } async function signHS256(data: string, secret: string): Promise { const key = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'], ); const signature = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(data)); return base64UrlEncode(new Uint8Array(signature)); } function base64UrlDecodeToString(value: string): string { const base64 = value.replace(/-/g, '+').replace(/_/g, '/'); const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '='); const binary = atob(padded); const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0)); return new TextDecoder().decode(bytes); } function base64UrlEncode(bytes: Uint8Array): string { let binary = ''; for (let index = 0; index < bytes.byteLength; index += 1) { binary += String.fromCharCode(bytes[index]); } return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); } function timingSafeEqual(left: string, right: string): boolean { if (left.length !== right.length) { return false; } let result = 0; for (let index = 0; index < left.length; index += 1) { result |= left.charCodeAt(index) ^ right.charCodeAt(index); } return result === 0; }