mirror of
https://github.com/streetwriters/notesnook-sync-server.git
synced 2026-02-12 19:22:45 +00:00
Compare commits
5 Commits
v1.0-beta.
...
v1.0-beta.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03f230dbca | ||
|
|
0a8c707387 | ||
|
|
8908b8c6ed | ||
|
|
da8df8973c | ||
|
|
7e50311c92 |
@@ -27,8 +27,6 @@ FROM build AS publish
|
||||
RUN dotnet publish -c Release -o /app/publish \
|
||||
#--runtime alpine-x64 \
|
||||
--self-contained true \
|
||||
/p:TrimMode=partial \
|
||||
/p:PublishTrimmed=true \
|
||||
/p:PublishSingleFile=true \
|
||||
/p:JsonSerializerIsReflectionEnabledByDefault=true \
|
||||
-a $TARGETARCH
|
||||
|
||||
@@ -247,7 +247,7 @@ namespace Notesnook.API.Hubs
|
||||
var chunks = PrepareChunks(
|
||||
userId,
|
||||
ids,
|
||||
size: 1000,
|
||||
size: 100,
|
||||
resetSync: device.IsSyncReset,
|
||||
maxBytes: 7 * 1024 * 1024
|
||||
);
|
||||
|
||||
@@ -91,11 +91,7 @@ namespace Notesnook.API.Repositories
|
||||
public void DeleteByUserId(string userId)
|
||||
{
|
||||
var filter = Builders<SyncItem>.Filter.Eq("UserId", userId);
|
||||
var writes = new List<WriteModel<SyncItem>>
|
||||
{
|
||||
new DeleteManyModel<SyncItem>(filter)
|
||||
};
|
||||
dbContext.AddCommand((handle, ct) => Collection.BulkWriteAsync(handle, writes, options: null, ct));
|
||||
dbContext.AddCommand((handle, ct) => Collection.DeleteManyAsync(handle, filter, null, ct));
|
||||
}
|
||||
|
||||
public void Upsert(SyncItem item, string userId, long dateSynced)
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace Notesnook.API.Services
|
||||
return result;
|
||||
}
|
||||
|
||||
const int MaxIdsPerChunk = 400_000;
|
||||
const int MaxIdsPerChunk = 25_000;
|
||||
public async Task AppendIdsAsync(string userId, string deviceId, string key, IEnumerable<ItemKey> ids)
|
||||
{
|
||||
var filter = DeviceIdsChunkFilter(userId, deviceId, key) & Builders<DeviceIdsChunk>.Filter.Where(x => x.Ids.Length < MaxIdsPerChunk);
|
||||
@@ -81,7 +81,7 @@ namespace Notesnook.API.Services
|
||||
|
||||
if (chunk != null)
|
||||
{
|
||||
var update = Builders<DeviceIdsChunk>.Update.PushEach(x => x.Ids, ids.Select(i => i.ToString()));
|
||||
var update = Builders<DeviceIdsChunk>.Update.AddToSetEach(x => x.Ids, ids.Select(i => i.ToString()));
|
||||
await repositories.DeviceIdsChunks.Collection.UpdateOneAsync(
|
||||
Builders<DeviceIdsChunk>.Filter.Eq(x => x.Id, chunk.Id),
|
||||
update
|
||||
|
||||
@@ -182,6 +182,7 @@ namespace Notesnook.API.Services
|
||||
|
||||
public async Task DeleteUserAsync(string userId)
|
||||
{
|
||||
logger.LogInformation("Deleting user {UserId}", userId);
|
||||
var cc = new CancellationTokenSource();
|
||||
|
||||
Repositories.Notes.DeleteByUserId(userId);
|
||||
|
||||
@@ -27,8 +27,6 @@ FROM build AS publish
|
||||
RUN dotnet publish -c Release -o /app/publish \
|
||||
#--runtime alpine-x64 \
|
||||
--self-contained true \
|
||||
/p:TrimMode=partial \
|
||||
/p:PublishTrimmed=true \
|
||||
/p:PublishSingleFile=true \
|
||||
/p:JsonSerializerIsReflectionEnabledByDefault=true \
|
||||
-a $TARGETARCH
|
||||
|
||||
@@ -27,8 +27,6 @@ FROM build AS publish
|
||||
RUN dotnet publish -c Release -o /app/publish \
|
||||
#--runtime alpine-x64 \
|
||||
--self-contained true \
|
||||
/p:TrimMode=partial \
|
||||
/p:PublishTrimmed=true \
|
||||
/p:PublishSingleFile=true \
|
||||
/p:JsonSerializerIsReflectionEnabledByDefault=true \
|
||||
-a $TARGETARCH
|
||||
|
||||
@@ -210,7 +210,19 @@ const server = Bun.serve({
|
||||
});
|
||||
}
|
||||
|
||||
// Proxy the request
|
||||
// Check if it's a YouTube URL and redirect instead of proxying
|
||||
if (isYouTubeEmbed(targetUrl)) {
|
||||
// YouTube URL detected, redirect to youtube-nocookie.com
|
||||
logRequest(req.method, targetUrl, 200);
|
||||
return new Response(serveYouTubeEmbed(targetUrl), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": "text/html; charset=utf-8",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Proxy the request for non-YouTube URLs
|
||||
const response = await proxyRequest(targetUrl);
|
||||
logRequest(req.method, targetUrl, response.status);
|
||||
return response;
|
||||
@@ -229,3 +241,80 @@ console.log(
|
||||
);
|
||||
console.log(`📋 Health check: http://${server.hostname}:${server.port}/health`);
|
||||
console.log(`🌍 Environment: ${Bun.env.NODE_ENV || "development"}`);
|
||||
|
||||
/**
|
||||
* This is required to bypass YouTube's Referrer Policy restrictions when
|
||||
* embedding videos on the mobile app. It basically "proxies" the Referrer and
|
||||
* allows any YouTube video to be embedded anywhere without restrictions.
|
||||
*/
|
||||
function serveYouTubeEmbed(url: string) {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="referrer" content="strict-origin-when-cross-origin">
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title>YouTube Video Embed</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box
|
||||
}
|
||||
|
||||
body, html {
|
||||
overflow: hidden;
|
||||
background:#000
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: block
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="${transformYouTubeUrl(
|
||||
url
|
||||
)}" allow="accelerometer;autoplay;clipboard-write;encrypted-media;gyroscope;picture-in-picture;web-share" allowfullscreen referrerpolicy="strict-origin-when-cross-origin" title="Video player"></iframe>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
// Check if URL is a YouTube embed (including youtube-nocookie.com)
|
||||
function isYouTubeEmbed(urlString: string) {
|
||||
const url = new URL(urlString);
|
||||
return (
|
||||
(url.hostname === "www.youtube.com" ||
|
||||
url.hostname === "youtube.com" ||
|
||||
url.hostname === "m.youtube.com" ||
|
||||
url.hostname === "www.youtube-nocookie.com" ||
|
||||
url.hostname === "youtube-nocookie.com") &&
|
||||
url.pathname.startsWith("/embed/")
|
||||
);
|
||||
}
|
||||
|
||||
// Transform YouTube URLs to use youtube-nocookie.com for enhanced privacy
|
||||
function transformYouTubeUrl(urlString: string): string {
|
||||
try {
|
||||
const url = new URL(urlString);
|
||||
|
||||
// Check if it's a YouTube domain
|
||||
if (
|
||||
url.hostname === "www.youtube.com" ||
|
||||
url.hostname === "youtube.com" ||
|
||||
url.hostname === "m.youtube.com"
|
||||
) {
|
||||
// Replace with youtube-nocookie.com
|
||||
url.hostname = "www.youtube-nocookie.com";
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
return urlString;
|
||||
} catch {
|
||||
return urlString;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user