chore: update TypeScript build info cache
This commit is contained in:
parent
7cb75e2d3b
commit
68f6c67240
2
.angular/cache/20.2.2/app/.tsbuildinfo
vendored
2
.angular/cache/20.2.2/app/.tsbuildinfo
vendored
File diff suppressed because one or more lines are too long
BIN
db/newtube.db
BIN
db/newtube.db
Binary file not shown.
@ -1073,20 +1073,58 @@ r.delete('/user/likes', authMiddleware, (req, res) => {
|
|||||||
return res.json(result);
|
return res.json(result);
|
||||||
});
|
});
|
||||||
|
|
||||||
r.get('/user/likes/status', authMiddleware, (req, res) => {
|
// Odysee image proxy to avoid CORS/ORB issues
|
||||||
const provider = req.query.provider ? String(req.query.provider) : '';
|
r.get('/img/odysee', async (req, res) => {
|
||||||
const videoId = req.query.videoId ? String(req.query.videoId) : '';
|
try {
|
||||||
if (!provider || !videoId) return res.status(400).json({ error: 'provider and videoId are required' });
|
const imageUrl = req.query.u ? String(req.query.u) : '';
|
||||||
const liked = isVideoLiked({ userId: req.user.id, provider, videoId });
|
if (!imageUrl) return res.status(400).json({ error: 'Missing image URL' });
|
||||||
return res.json({ liked });
|
|
||||||
|
// Only allow specific Odysee domains for security
|
||||||
|
const allowedHosts = [
|
||||||
|
'thumbnails.odycdn.com',
|
||||||
|
'thumbs.odycdn.com',
|
||||||
|
'od.lk',
|
||||||
|
'cdn.lbryplayer.xyz',
|
||||||
|
'spee.ch',
|
||||||
|
'cdn.lbryplayer.xyz',
|
||||||
|
'thumbnails.lbry.com',
|
||||||
|
'static.odycdn.com',
|
||||||
|
'thumbnails.odycdn.com'
|
||||||
|
];
|
||||||
|
|
||||||
|
const url = new URL(imageUrl);
|
||||||
|
if (!allowedHosts.includes(url.hostname)) {
|
||||||
|
return res.status(403).json({ error: 'Forbidden domain' });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the image
|
||||||
|
const response = await fetch(imageUrl, {
|
||||||
|
headers: { 'User-Agent': 'NewTube/1.0' },
|
||||||
|
redirect: 'follow'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
return res.status(response.status).send(`Error fetching image: ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward the image with appropriate caching
|
||||||
|
res.setHeader('Cache-Control', 'public, max-age=600');
|
||||||
|
res.setHeader('Content-Type', response.headers.get('content-type') || 'image/jpeg');
|
||||||
|
|
||||||
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
|
res.send(Buffer.from(arrayBuffer));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error proxying Odysee image:', error);
|
||||||
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use('/api', r);
|
app.use('/api', r);
|
||||||
|
// Alias to support Angular dev proxy paths in both dev and production builds
|
||||||
|
app.use('/proxy/api', r);
|
||||||
// Mount dedicated Rumble router (browse, search, video)
|
// Mount dedicated Rumble router (browse, search, video)
|
||||||
app.use('/api/rumble', rumbleRouter);
|
app.use('/api/rumble', rumbleRouter);
|
||||||
|
|
||||||
app.get('/health', (_req, res) => res.json({ ok: true }));
|
|
||||||
|
|
||||||
// -------------------- Client config from environment --------------------
|
// -------------------- Client config from environment --------------------
|
||||||
function jsVal(v) { return JSON.stringify(v == null ? '' : v); }
|
function jsVal(v) { return JSON.stringify(v == null ? '' : v); }
|
||||||
app.get(['/assets/config.local.js', '/config.js'], (_req, res) => {
|
app.get(['/assets/config.local.js', '/config.js'], (_req, res) => {
|
||||||
@ -1129,7 +1167,6 @@ async function forwardJson(req, res, base) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.all('/api/dm/*', (req, res) => forwardJson(req, res, 'https://api.dailymotion.com'));
|
app.all('/api/dm/*', (req, res) => forwardJson(req, res, 'https://api.dailymotion.com'));
|
||||||
app.all('/api/odysee/*', (req, res) => forwardJson(req, res, 'https://api.na-backend.odysee.com'));
|
|
||||||
app.all('/api/twitch-api/*', (req, res) => forwardJson(req, res, 'https://api.twitch.tv'));
|
app.all('/api/twitch-api/*', (req, res) => forwardJson(req, res, 'https://api.twitch.tv'));
|
||||||
app.all('/api/twitch-auth/*', (req, res) => forwardJson(req, res, 'https://id.twitch.tv'));
|
app.all('/api/twitch-auth/*', (req, res) => forwardJson(req, res, 'https://id.twitch.tv'));
|
||||||
|
|
||||||
|
@ -66,6 +66,17 @@ export class YoutubeApiService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build a proxied URL through our backend to avoid ORB/CORS on Odysee CDN
|
||||||
|
private proxiedOdyseeThumb(url?: string): string {
|
||||||
|
const norm = this.normalizeOdyseeThumb(url);
|
||||||
|
if (!norm) return '';
|
||||||
|
try {
|
||||||
|
return `/proxy/api/img/odysee?u=${encodeURIComponent(norm)}`;
|
||||||
|
} catch {
|
||||||
|
return `/proxy/api/img/odysee?u=${encodeURIComponent(String(norm))}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ... (rest of the code remains the same)
|
// ... (rest of the code remains the same)
|
||||||
|
|
||||||
// ===================== Twitch Search Helpers =====================
|
// ===================== Twitch Search Helpers =====================
|
||||||
@ -634,7 +645,7 @@ export class YoutubeApiService {
|
|||||||
const lbryUrl = i?.permanent_url || i?.canonical_url || '';
|
const lbryUrl = i?.permanent_url || i?.canonical_url || '';
|
||||||
const webUrl = this.lbryToOdyseeUrl(lbryUrl) || (i?.name ? `https://odysee.com/${i.name}` : '');
|
const webUrl = this.lbryToOdyseeUrl(lbryUrl) || (i?.name ? `https://odysee.com/${i.name}` : '');
|
||||||
const thumbRaw = val?.thumbnail?.url || '';
|
const thumbRaw = val?.thumbnail?.url || '';
|
||||||
const thumb = this.normalizeOdyseeThumb(thumbRaw);
|
const thumb = this.proxiedOdyseeThumb(thumbRaw);
|
||||||
const publishedAt = val?.release_time ? new Date(val.release_time * 1000).toISOString() : '';
|
const publishedAt = val?.release_time ? new Date(val.release_time * 1000).toISOString() : '';
|
||||||
const duration = val?.video?.duration || 0;
|
const duration = val?.video?.duration || 0;
|
||||||
const views = (i?.meta?.view_count != null) ? Number(i.meta.view_count) : 0;
|
const views = (i?.meta?.view_count != null) ? Number(i.meta.view_count) : 0;
|
||||||
@ -648,7 +659,7 @@ export class YoutubeApiService {
|
|||||||
thumbnail: thumb,
|
thumbnail: thumb,
|
||||||
uploaderName,
|
uploaderName,
|
||||||
uploaderUrl: channel?.permanent_url ? this.lbryToOdyseeUrl(channel.permanent_url) : '',
|
uploaderUrl: channel?.permanent_url ? this.lbryToOdyseeUrl(channel.permanent_url) : '',
|
||||||
uploaderAvatar: this.normalizeOdyseeThumb(channelVal?.thumbnail?.url) || thumb,
|
uploaderAvatar: this.proxiedOdyseeThumb(channelVal?.thumbnail?.url) || thumb,
|
||||||
uploadedDate: publishedAt,
|
uploadedDate: publishedAt,
|
||||||
duration: Number(duration || 0),
|
duration: Number(duration || 0),
|
||||||
views: views,
|
views: views,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user