Skip to content

Commit 481210b

Browse files
event.puter//user puter and automatic cors exemption handling in puter workers (#1342)
* event.puter * automatic opt out cors handling * remove "starting puterjs initialization" log * Set compatibility date * remove body log
1 parent cc26704 commit 481210b

File tree

3 files changed

+67
-12
lines changed

3 files changed

+67
-12
lines changed

src/backend/src/services/worker/src/s2w-router.js

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ function inits2w() {
44
// s2w router itself: Not part of any package, just a simple router.
55
const s2w = {
66
routing: true,
7+
handleCors: true,
78
map: new Map(),
89
custom(eventName, route, eventListener) {
910
const matchExp = match(route);
@@ -28,33 +29,75 @@ function inits2w() {
2829
delete(...args) {
2930
this.custom("DELETE", ...args)
3031
},
32+
async handleOptions(request) {
33+
const corsHeaders = {
34+
"Access-Control-Allow-Origin": "*",
35+
"Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS",
36+
"Access-Control-Max-Age": "86400",
37+
};
38+
if (
39+
request.headers.get("Origin") !== null &&
40+
request.headers.get("Access-Control-Request-Method") !== null &&
41+
request.headers.get("Access-Control-Request-Headers") !== null
42+
) {
43+
// Handle CORS preflight requests.
44+
return new Response(null, {
45+
headers: {
46+
...corsHeaders,
47+
"Access-Control-Allow-Headers": request.headers.get(
48+
"Access-Control-Request-Headers",
49+
),
50+
},
51+
});
52+
} else {
53+
// Handle standard OPTIONS request.
54+
return new Response(null, {
55+
headers: {
56+
Allow: "GET, HEAD, POST, OPTIONS",
57+
},
58+
});
59+
}
60+
},
61+
/**
62+
*
63+
* @param {FetchEvent } event
64+
* @returns
65+
*/
3166
async route(event) {
3267
if (!globalThis.puter) {
33-
console.log("Puter not loaded, initializing...");
3468
const success = init_puter_portable(globalThis.puter_auth, globalThis.puter_endpoint || "https://api.puter.com");
35-
console.log("Puter.js initialized successfully");
3669
}
37-
70+
if (event.request.headers.has("puter-authorization")) {
71+
event.puter = init_puter_portable(event.request.headers.get("puter-authorization"), globalThis.puter_endpoint || "https://api.puter.com", "userPuter");
72+
}
73+
3874
const mappings = this.map.get(event.request.method);
75+
if (this.handleCors && event.request.method === "OPTIONS" && !mappings) {
76+
return this.handleOptions(event.request);
77+
}
3978
const url = new URL(event.request.url);
4079
try {
4180
for (const mapping of mappings) {
4281
// return new Response(JSON.stringify(mapping))
4382
const results = mapping[0](url.pathname)
4483
if (results) {
4584
event.params = results.params;
46-
return mapping[1](event);
85+
const response = await mapping[1](event);
86+
if (this.handleCors && !response.headers.has("access-control-allow-origin")) {
87+
response.headers.set("Access-Control-Allow-Origin", "*");
88+
}
89+
return response;
4790
}
4891
}
4992
} catch (e) {
50-
return new Response(e, {status: 500, statusText: "Server Error"})
93+
return new Response(e, { status: 500, statusText: "Server Error" })
5194
}
5295

53-
return new Response("Path not found", {status: 404, statusText: "Not found"});
96+
return new Response("Path not found", { status: 404, statusText: "Not found" });
5497
}
5598
}
5699
globalThis.s2w = s2w;
57-
self.addEventListener("fetch", (event)=> {
100+
self.addEventListener("fetch", (event) => {
58101
if (!s2w.routing)
59102
return false;
60103
event.respondWith(s2w.route(event));

src/backend/src/services/worker/template/puter-portable.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,29 @@ if (globalThis.Cloudflare) {
1515
}
1616
}
1717

18-
globalThis.init_puter_portable = (auth, apiOrigin) => {
19-
console.log("Starting puter.js initialization");
20-
18+
globalThis.init_puter_portable = (auth, apiOrigin, type) => {
2119
// Who put C in my JS??
2220
/*
2321
* This is a hack to include the puter.js file.
2422
* It is not a good idea to do this, but it is the only way to get the puter.js file to work.
2523
* The puter.js file is handled by the C preprocessor here because webpack cant behave with already minified files.
2624
* The C preprocessor basically just includes the file and then we can use the puter.js file in the worker.
2725
*/
28-
#include "../../../../../puter-js/dist/puter.js"
26+
if (type === "userPuter") {
27+
const goodContext = {}
28+
Object.getOwnPropertyNames(globalThis).forEach(name => { try { goodContext[name] = globalThis[name]; } catch {} })
29+
goodContext.globalThis = goodContext;
30+
goodContext.addEventListener = ()=>{};
31+
// @ts-ignore
32+
with (goodContext) {
33+
#include "../../../../../puter-js/dist/puter.js"
34+
}
35+
goodContext.puter.setAPIOrigin(apiOrigin);
36+
goodContext.puter.setAuthToken(auth);
37+
return goodContext.puter;
38+
} else {
39+
#include "../../../../../puter-js/dist/puter.js"
40+
}
2941
puter.setAPIOrigin(apiOrigin);
3042
puter.setAuthToken(auth);
3143
}

src/backend/src/services/worker/workerUtils/cloudflareDeploy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ async function getWorker(userData, authorization, workerId) {
1919
await cfFetch(`${WORKERS_BASE_URL}/scripts/${calculateWorkerName(userData.username, workerId)}`, "GET");
2020
}
2121
async function createWorker(userData, authorization, workerId, body, PREAMBLE_LENGTH) {
22-
console.log(body)
2322
const formData = new FormData();
2423

2524
const workerMetaData = {
2625

2726
body_part: "swCode",
27+
compatibility_date: "2025-07-15",
2828
bindings: [
2929
{
3030
type: "secret_text",

0 commit comments

Comments
 (0)