diff --git a/biome.json b/biome.json index be4bcaf..0c25400 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.7.2/schema.json", + "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json", "organizeImports": { "enabled": true }, @@ -17,11 +17,11 @@ "formatWithErrors": true, "indentStyle": "tab", "indentWidth": 2, - "lineWidth": 150 + "lineWidth": 120 }, "javascript": { "formatter": { - "trailingComma": "none", + "trailingCommas": "all", "arrowParentheses": "asNeeded" } }, diff --git a/package.json b/package.json index ce05cf6..f03faf5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "simple-proxy", "private": true, - "version": "2.1.4", + "version": "2.2.0", "scripts": { "prepare": "nitropack prepare", "dev": "nitropack dev", @@ -12,6 +12,9 @@ "preinstall": "npx only-allow pnpm" }, "dependencies": { + "@elysiajs/cors": "^1.0.2", + "elysia": "^1.0.16", + "eventemitter3": "^5.0.1", "fetch-cookie": "^3.0.1", "h3": "^1.10.0", "nitropack": "^2.8.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7dc6107..210d470 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,15 @@ importers: .: dependencies: + '@elysiajs/cors': + specifier: ^1.0.2 + version: 1.0.2(elysia@1.0.16(@sinclair/typebox@0.32.29)) + elysia: + specifier: ^1.0.16 + version: 1.0.16(@sinclair/typebox@0.32.29) + eventemitter3: + specifier: ^5.0.1 + version: 5.0.1 fetch-cookie: specifier: ^3.0.1 version: 3.0.1 @@ -30,6 +39,11 @@ packages: '@cloudflare/kv-asset-handler@0.3.0': resolution: {integrity: sha512-9CB/MKf/wdvbfkUdfrj+OkEwZ5b7rws0eogJ4293h+7b6KX5toPwym+VQKmILafNB9YiehqY0DlNrDcDhdWHSQ==} + '@elysiajs/cors@1.0.2': + resolution: {integrity: sha512-2X+wes5M2SdSaI4lGp0YBbTK35y9TtjjjFMjmQNjMonUXxtOrAR7cA0lsSIvHQ8UTd9z+mMBn7NyBhWaKxq0jA==} + peerDependencies: + elysia: '>= 1.0.2' + '@esbuild/aix-ppc64@0.19.11': resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} engines: {node: '>=12'} @@ -401,6 +415,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + '@sinclair/typebox@0.32.29': + resolution: {integrity: sha512-GWKskKPGQV0vVYizqCu0E1YLwGthvlkDqpRxB3iBuqxJ8dN/9n1cnDRSQHF59GMoxDJwzSgmxpU617SidtUnMw==} + '@sindresorhus/merge-streams@1.0.0': resolution: {integrity: sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==} engines: {node: '>=18'} @@ -582,6 +599,10 @@ packages: cookie-es@1.0.0: resolution: {integrity: sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ==} + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -667,6 +688,30 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + elysia@1.0.15: + resolution: {integrity: sha512-18dJnNV3X1a7vYKQHOQ9yS+upg6v0gb/L3kNlFwoq4grUPCpOi4II6ViXtWs1Qd1uWyqDJ+S6oUGMGlhIneehg==} + peerDependencies: + '@sinclair/typebox': '>= 0.31.0' + openapi-types: '>= 12.0.0' + typescript: '>= 5.0.0' + peerDependenciesMeta: + openapi-types: + optional: true + typescript: + optional: true + + elysia@1.0.16: + resolution: {integrity: sha512-6TvgaTA8o3GwUkBZ2ulm4NBicUZxSLWS5mRFB8sckKs//ybgM6O5GqOmI6VGqWSopAHI3pXYd8YhII69agCj9A==} + peerDependencies: + '@sinclair/typebox': '>= 0.31.0' + openapi-types: '>= 12.0.0' + typescript: '>= 5.0.0' + peerDependenciesMeta: + openapi-types: + optional: true + typescript: + optional: true + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -700,6 +745,9 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -708,6 +756,9 @@ packages: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} + fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} @@ -715,6 +766,9 @@ packages: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} + fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} @@ -1569,6 +1623,10 @@ snapshots: dependencies: mime: 3.0.0 + '@elysiajs/cors@1.0.2(elysia@1.0.16(@sinclair/typebox@0.32.29))': + dependencies: + elysia: 1.0.16(@sinclair/typebox@0.32.29) + '@esbuild/aix-ppc64@0.19.11': optional: true @@ -1852,6 +1910,8 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + '@sinclair/typebox@0.32.29': {} + '@sindresorhus/merge-streams@1.0.0': {} '@types/estree@1.0.1': {} @@ -2046,6 +2106,8 @@ snapshots: cookie-es@1.0.0: {} + cookie@0.6.0: {} + core-util-is@1.0.3: {} crc-32@1.2.2: {} @@ -2099,6 +2161,23 @@ snapshots: ee-first@1.1.1: {} + elysia@1.0.15(@sinclair/typebox@0.32.29): + dependencies: + '@sinclair/typebox': 0.32.29 + cookie: 0.6.0 + eventemitter3: 5.0.1 + fast-decode-uri-component: 1.0.1 + fast-querystring: 1.1.2 + + elysia@1.0.16(@sinclair/typebox@0.32.29): + dependencies: + '@sinclair/typebox': 0.32.29 + cookie: 0.6.0 + elysia: 1.0.15(@sinclair/typebox@0.32.29) + eventemitter3: 5.0.1 + fast-decode-uri-component: 1.0.1 + fast-querystring: 1.1.2 + emoji-regex@8.0.0: {} encodeurl@1.0.2: {} @@ -2143,6 +2222,8 @@ snapshots: etag@1.8.1: {} + eventemitter3@5.0.1: {} + execa@5.1.1: dependencies: cross-spawn: 7.0.3 @@ -2167,6 +2248,8 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 + fast-decode-uri-component@1.0.1: {} + fast-fifo@1.3.2: {} fast-glob@3.3.2: @@ -2177,6 +2260,10 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.5 + fast-querystring@1.1.2: + dependencies: + fast-decode-uri-component: 1.0.1 + fastq@1.15.0: dependencies: reusify: 1.0.4 diff --git a/src/routes/[...dest].ts b/src/routes/[...dest].ts index c875f7c..1f72df6 100644 --- a/src/routes/[...dest].ts +++ b/src/routes/[...dest].ts @@ -24,7 +24,15 @@ export default defineEventHandler(async event => { }); } - if (checkBlacklistedTarget(destination) || !isValidURL(destination)) { + if ( + checkBlacklistedTarget(destination) || + !isValidURL(destination) || + isCorsOriginAllowed(event.headers.get("origin") ?? undefined, { + origin: (origin: string) => { + return origin !== "https://xpui.app.spotify.com"; + } + }) + ) { return await sendJson({ event, status: 400, diff --git a/src/utils/sending.ts b/src/utils/sending.ts index 8a5e106..16eca3f 100644 --- a/src/utils/sending.ts +++ b/src/utils/sending.ts @@ -6,5 +6,10 @@ export async function sendJson(ops: { status?: number; }) { setResponseStatus(ops.event, ops.status ?? 200); + appendCorsHeaders(ops.event, { + origin: (origin: string) => { + return origin === "https://xpui.app.spotify.com"; + }, + }); await send(ops.event, JSON.stringify(ops.data, null, 2), "application/json"); }