Protect sync pull with approved devices

This commit is contained in:
2026-05-08 18:20:01 -04:00
parent b4b862517a
commit 3544f644b1
4 changed files with 444 additions and 1 deletions
+37 -1
View File
@@ -1,5 +1,9 @@
import type { Env } from "./bindings.js";
import { withAuthenticatedApiControls, withPublicApiControls } from "./api_controls.js";
import {
withApprovedDeviceApiControls,
withAuthenticatedApiControls,
withPublicApiControls,
} from "./api_controls.js";
import {
DevicePermissionError,
DevicePersistenceError,
@@ -31,6 +35,7 @@ import {
parsePublicSigningKeysDocument,
publicSigningKeysKvKey,
} from "./signing_keys.js";
import { SyncRequestError, SyncSchemaError, syncPullDocument } from "./sync_pull.js";
import { jsonResponse } from "./responses.js";
export default {
@@ -169,6 +174,37 @@ export async function handleRequest(request: Request, env: Env): Promise<Respons
},
);
}
if (url.pathname === "/api/sync/pull") {
return withApprovedDeviceApiControls(
request,
env,
"sync.pull",
["GET"],
async (context) => {
try {
return jsonResponse(await syncPullDocument(url, env, context), 200, {
"Cache-Control": "no-store",
});
} catch (error) {
if (error instanceof SyncRequestError) {
return jsonResponse(
{ error: "invalid_sync_pull" },
400,
{ "Cache-Control": "no-store" },
);
}
if (error instanceof SyncSchemaError) {
return jsonResponse(
{ error: "sync_pull_invalid" },
500,
{ "Cache-Control": "no-store" },
);
}
throw error;
}
},
);
}
if (url.pathname === "/api/plugins/signing-keys") {
return withPublicApiControls(request, env, "plugins.signing_keys", ["GET"], () =>
handlePublicSigningKeys(env),