diff --git a/package-lock.json b/package-lock.json index c095f4e..3e1f9ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,8 +5,9 @@ "packages": { "": { "dependencies": { + "@supabase/supabase-js": "^2.46.1", "jose": "^5.9.6", - "wrangler": "^3.87.0" + "wrangler": "^3.91.0" } }, "node_modules/@cloudflare/kv-asset-handler": { @@ -28,6 +29,7 @@ "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" @@ -43,6 +45,7 @@ "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "darwin" @@ -58,6 +61,7 @@ "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -73,6 +77,7 @@ "cpu": [ "arm64" ], + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -88,6 +93,7 @@ "cpu": [ "x64" ], + "license": "Apache-2.0", "optional": true, "os": [ "win32" @@ -97,9 +103,10 @@ } }, "node_modules/@cloudflare/workers-shared": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.7.1.tgz", - "integrity": "sha512-46cP5FCrl3TrvHeoHLb5SRuiDMKH5kc9Yvo36SAfzt8dqJI/qJRoY1GP3ioHn/gP7v2QIoUOTAzIl7Ml7MnfrA==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.9.0.tgz", + "integrity": "sha512-eP6Ir45uPbKnpADVzUCtkRUYxYxjB1Ew6n/whTJvHu8H4m93USHAceCMm736VBZdlxuhXXUjEP3fCUxKPn+cfw==", + "license": "MIT OR Apache-2.0", "dependencies": { "mime": "^3.0.0", "zod": "^3.22.3" @@ -112,6 +119,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -497,6 +505,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "license": "MIT", "engines": { "node": ">=14" } @@ -505,6 +514,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -512,17 +522,93 @@ "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@supabase/auth-js": { + "version": "2.65.1", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.65.1.tgz", + "integrity": "sha512-IA7i2Xq2SWNCNMKxwmPlHafBQda0qtnFr8QnyyBr+KaSxoXXqEzFCnQ1dGTy6bsZjVBgXu++o3qrDypTspaAPw==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.3.tgz", + "integrity": "sha512-sOLXy+mWRyu4LLv1onYydq+10mNRQ4rzqQxNhbrKLTLTcdcmS9hbWif0bGz/NavmiQfPs4ZcmQJp4WqOXlR4AQ==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", + "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.16.3.tgz", + "integrity": "sha512-HI6dsbW68AKlOPofUjDTaosiDBCtW4XAm0D18pPwxoW3zKOE2Ru13Z69Wuys9fd6iTpfDViNco5sgrtnP0666A==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.10.9", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.10.9.tgz", + "integrity": "sha512-0AjN65VDNIScZzrrPaVvlND4vbgVS+j9Wcy3zf7e+l9JY4IwCTahFenPLcKy9bkr7KY0wfB7MkipZPKxMaDnjw==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/ws": "^8.5.10", + "ws": "^8.18.0" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.1.tgz", + "integrity": "sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.46.2", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.46.2.tgz", + "integrity": "sha512-5FEzYMZhfIZrMWEqo5/dQincvrhM+DeMWH3/okeZrkBBW1AJxblOQhnhF4/dfNYK25oZ1O8dAnnxZ9gQqdr40w==", + "license": "MIT", + "dependencies": { + "@supabase/auth-js": "2.65.1", + "@supabase/functions-js": "2.4.3", + "@supabase/node-fetch": "2.6.15", + "@supabase/postgrest-js": "1.16.3", + "@supabase/realtime-js": "2.10.9", + "@supabase/storage-js": "2.7.1" + } + }, "node_modules/@types/node": { "version": "22.8.6", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.6.tgz", @@ -541,10 +627,26 @@ "@types/node": "*" } }, + "node_modules/@types/phoenix": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz", + "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -556,6 +658,7 @@ "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", "dependencies": { "acorn": "^8.11.0" }, @@ -567,6 +670,7 @@ "version": "1.0.55", "resolved": "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz", "integrity": "sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==", + "license": "MIT", "dependencies": { "printable-characters": "^1.0.42" } @@ -581,6 +685,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/capnp-ts/-/capnp-ts-0.7.0.tgz", "integrity": "sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==", + "license": "MIT", "dependencies": { "debug": "^4.3.1", "tslib": "^2.2.0" @@ -605,6 +710,7 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -612,7 +718,8 @@ "node_modules/data-uri-to-buffer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz", - "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==" + "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==", + "license": "MIT" }, "node_modules/date-fns": { "version": "4.1.0", @@ -628,6 +735,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -705,6 +813,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -738,6 +847,7 @@ "version": "2.0.12", "resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz", "integrity": "sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==", + "license": "Unlicense", "dependencies": { "data-uri-to-buffer": "^2.0.0", "source-map": "^0.6.1" @@ -746,7 +856,8 @@ "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause" }, "node_modules/hasown": { "version": "2.0.2", @@ -812,9 +923,10 @@ } }, "node_modules/miniflare": { - "version": "3.20241106.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241106.0.tgz", - "integrity": "sha512-PjOoJKjUUofCueQskfhXlGvvHxZj36UAJAp1DnquMK88MFF50zCULblh0KXMSNM+bXeQYA94Gj06a7kfmBGxPw==", + "version": "3.20241106.1", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241106.1.tgz", + "integrity": "sha512-dM3RBlJE8rUFxnqlPCaFCq0E7qQqEQvKbYX7W/APGCK+rLcyLmEBzC4GQR/niXdNM/oV6gdg9AA50ghnn2ALuw==", + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "0.8.1", "acorn": "^8.8.0", @@ -839,12 +951,14 @@ "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/mustache": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", "bin": { "mustache": "bin/mustache" } @@ -903,7 +1017,8 @@ "node_modules/printable-characters": { "version": "1.0.42", "resolved": "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz", - "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==" + "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==", + "license": "Unlicense" }, "node_modules/readdirp": { "version": "4.0.2", @@ -991,6 +1106,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -1006,6 +1122,7 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/stacktracey/-/stacktracey-2.1.8.tgz", "integrity": "sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==", + "license": "Unlicense", "dependencies": { "as-table": "^1.0.36", "get-source": "^2.0.12" @@ -1015,6 +1132,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", + "license": "MIT", "engines": { "node": ">=4", "npm": ">=6" @@ -1032,10 +1150,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/ufo": { "version": "1.5.4", @@ -1047,6 +1172,7 @@ "version": "5.28.4", "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" }, @@ -1062,9 +1188,9 @@ }, "node_modules/unenv": { "name": "unenv-nightly", - "version": "2.0.0-20241024-111401-d4156ac", - "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20241024-111401-d4156ac.tgz", - "integrity": "sha512-xJO1hfY+Te+/XnfCYrCbFbRcgu6XEODND1s5wnVbaBCkuQX7JXF7fHEXPrukFE2j8EOH848P8QN19VO47XN8hw==", + "version": "2.0.0-20241121-161142-806b5c0", + "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20241121-161142-806b5c0.tgz", + "integrity": "sha512-RnFOasE/O0Q55gBkNB1b84OgKttgLEijGO0JCWpbn+O4XxpyCQg89NmcqQ5RGUiy4y+rMIrKzePTquQcLQF5pQ==", "license": "MIT", "dependencies": { "defu": "^6.1.4", @@ -1073,11 +1199,28 @@ "ufo": "^1.5.4" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/workerd": { "version": "1.20241106.1", "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241106.1.tgz", "integrity": "sha512-1GdKl0kDw8rrirr/ThcK66Kbl4/jd4h8uHx5g7YHBrnenY5SX1UPuop2cnCzYUxlg55kPjzIqqYslz1muRFgFw==", "hasInstallScript": true, + "license": "Apache-2.0", "bin": { "workerd": "bin/workerd" }, @@ -1093,13 +1236,13 @@ } }, "node_modules/wrangler": { - "version": "3.87.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.87.0.tgz", - "integrity": "sha512-BExktnSLeGgG+uxgnr4h9eZ5nefdpTVcTHR+gEIWRvqk07XL04nJwpPYAOIPKPpB7E2tMdDJgNLGQN/CY6e1xQ==", + "version": "3.91.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.91.0.tgz", + "integrity": "sha512-Hdzn6wbY9cz5kL85ZUvWLwLIH7nPaEVRblfms40jhRf4qQO/Zf74aFlku8rQFbe8/2aVZFaxJVfBd6JQMeMSBQ==", "license": "MIT OR Apache-2.0", "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", - "@cloudflare/workers-shared": "0.7.1", + "@cloudflare/workers-shared": "0.9.0", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "blake3-wasm": "^2.1.5", @@ -1107,14 +1250,14 @@ "date-fns": "^4.1.0", "esbuild": "0.17.19", "itty-time": "^1.0.6", - "miniflare": "3.20241106.0", + "miniflare": "3.20241106.1", "nanoid": "^3.3.3", "path-to-regexp": "^6.3.0", "resolve": "^1.22.8", "resolve.exports": "^2.0.2", "selfsigned": "^2.0.1", "source-map": "^0.6.1", - "unenv": "npm:unenv-nightly@2.0.0-20241024-111401-d4156ac", + "unenv": "npm:unenv-nightly@2.0.0-20241121-161142-806b5c0", "workerd": "1.20241106.1", "xxhash-wasm": "^1.0.1" }, @@ -1167,6 +1310,7 @@ "version": "3.3.4", "resolved": "https://registry.npmjs.org/youch/-/youch-3.3.4.tgz", "integrity": "sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==", + "license": "MIT", "dependencies": { "cookie": "^0.7.1", "mustache": "^4.2.0", @@ -1177,6 +1321,7 @@ "version": "3.23.8", "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index d7b5925..80132ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,8 @@ { "dependencies": { "jose": "^5.9.6", - "wrangler": "^3.87.0" + "wrangler": "^3.91.0", + "@supabase/supabase-js": "^2.46.1" + } } diff --git a/src/enums/integration-type.js b/src/enums/integration-type.js index 6f7e4b1..7a4e521 100644 --- a/src/enums/integration-type.js +++ b/src/enums/integration-type.js @@ -7,4 +7,6 @@ export const IntegrationTypeEnum = { AUTH0USERINFO : 'auth0_userinfo', AUTH0CALLBACKREDIRECT : 'auth0_callback_redirect', AUTH0REFRESH: 'auth0_refresh', + SUPABASEPASSWORDLESSAUTH: 'supabase_passwordless_auth', + SUPABASEPASSWORDLESSVERIFY: 'supabase_passwordless_verify', } diff --git a/src/index.js b/src/index.js index 7a3dd79..217f9d6 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ import { safeStringify, generateJsonResponse } from "./common"; const { jwtAuth } = await import('./auth'); +const responses = await import('./responses'); const { ValueMapper } = await import('./mapping'); const { setCorsHeaders } = await import('./cors'); const { PathOperator } = await import('./path-ops'); @@ -9,6 +10,7 @@ const { createProxiedRequest } = await import('./requests'); const { IntegrationTypeEnum } = await import('./enums/integration-type'); const { ServerlessAPIGatewayContext } = await import('./types/serverless_api_gateway_context'); const { auth0CallbackHandler, validateIdToken, getProfile, redirectToLogin, refreshToken } = await import('./integrations/auth0'); +const { supabaseEmailOTP, supabasePhoneOTP, supabaseVerifyOTP, supabaseJwtVerify } = await import('./integrations/supabase-auth'); export default { async fetch(request, env, ctx) { @@ -64,6 +66,7 @@ export default { try { sagContext.jwtPayload = await jwtAuth(request, sagContext.apiConfig); } catch (error) { + console.error('Error validating JWT', error.message); if (error instanceof AuthError) { return setPoweredByHeader( setCorsHeaders( @@ -79,8 +82,7 @@ export default { return setPoweredByHeader(setCorsHeaders(request, responses.internalServerErrorResponse(), sagContext.apiConfig.cors)); } } - } - else if (sagContext.apiConfig.authorizer && matchedPath.config.auth && sagContext.apiConfig.authorizer.type == 'auth0') { + } else if (sagContext.apiConfig.authorizer && matchedPath.config.auth && sagContext.apiConfig.authorizer.type == 'auth0') { try { sagContext.jwtPayload = await validateIdToken(request, null, sagContext.apiConfig.authorizer); } catch (error) { @@ -99,6 +101,27 @@ export default { return setPoweredByHeader(setCorsHeaders(request, responses.internalServerErrorResponse(), sagContext.apiConfig.cors)); } } + } else if (sagContext.apiConfig.authorizer && matchedPath.config.auth && sagContext.apiConfig.authorizer.type == 'supabase') { + try { + sagContext.jwtPayload = await supabaseJwtVerify(request, sagContext.apiConfig.authorizer); + console.log('JWT Payload:', sagContext.jwtPayload); + } catch (error) { + console.error('Error validating JWT', error.message); + if (error instanceof AuthError) { + return setPoweredByHeader( + setCorsHeaders( + request, + new Response(safeStringify({ error: error.message, code: error.code }), { + status: error.statusCode, + headers: { 'Content-Type': 'application/json' }, + }), + sagContext.apiConfig.cors + ), + ); + } else { + return setPoweredByHeader(setCorsHeaders(request, responses.internalServerErrorResponse(), sagContext.apiConfig.cors)); + } + } } if (matchedPath.config.integration && matchedPath.config.integration.type == IntegrationTypeEnum.HTTP_PROXY) { @@ -219,6 +242,39 @@ export default { return redirectToLogin({ state: urlParams.get('state') }, sagContext.apiConfig.authorizer); } else if (matchedPath.config.integration && matchedPath.config.integration.type == IntegrationTypeEnum.AUTH0REFRESH) { return this.refreshTokenLogic(request, env, sagContext); + } else if (matchedPath.config.integration && matchedPath.config.integration.type == IntegrationTypeEnum.SUPABASEPASSWORDLESSAUTH) { + const requestBody = await request.json(); + const email = requestBody.email; + const phone = requestBody.phone; + + if (email) { + return supabaseEmailOTP(env, email); + } else if (phone) { + return supabasePhoneOTP(env, phone); + } else { + return new Response(safeStringify({ error: 'Missing email or phone', code: 'missing_email_or_phone' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); + } + } else if (matchedPath.config.integration && matchedPath.config.integration.type == IntegrationTypeEnum.SUPABASEPASSWORDLESSVERIFY) { + const requestBody = await request.json(); + const token = requestBody.token; + const email = requestBody.email; + const phone = requestBody.phone; + + if (!token || (!email && !phone)) { + return new Response(safeStringify({ error: 'Missing token, email, or phone', code: 'missing_token_or_contact' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); + } + + const response = await supabaseVerifyOTP(env, email, phone, token); + return setPoweredByHeader(setCorsHeaders(request, + new Response(safeStringify(response), { status: 200, headers: { 'Content-Type': 'application/json' }, }), + sagContext.apiConfig.cors + )); } else { return setPoweredByHeader( setCorsHeaders( diff --git a/src/integrations/supabase-auth.js b/src/integrations/supabase-auth.js new file mode 100644 index 0000000..449687a --- /dev/null +++ b/src/integrations/supabase-auth.js @@ -0,0 +1,99 @@ +import { jwtVerify, errors } from 'jose'; +import { createClient } from '@supabase/supabase-js'; +import { AuthError } from "../types/error_types"; + +async function supabaseEmailOTP(env, email, shouldCreateUser = true) { + const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_KEY); + + const { data, error } = await supabase.auth.signInWithOtp({ + email, + options: { + shouldCreateUser + }, + }) + + return new Response(JSON.stringify({ message: 'OTP sent successfully' }), { headers: { 'Content-Type': 'application/json' } }); +} + +async function supabasePhoneOTP(env, phone, shouldCreateUser = true) { + const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_KEY); + + const { data, error } = await supabase.auth.signInWithOtp({ + phone, + options: { + shouldCreateUser + }, + }) + + return new Response(JSON.stringify({ message: 'OTP sent successfully' }), { headers: { 'Content-Type': 'application/json' } }); +} + + +async function supabaseVerifyOTP(env, email, phone, token) { + const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_KEY); + + const { data, error } = await supabase.auth.verifyOtp({ + [email ? 'email' : 'phone']: email || phone, + token, + type: email ? 'email' : 'sms', + }); + + if (error) { + throw new AuthError(error.message); + } + + console.log(data); + return data.session; +} + +async function supabaseJwtVerify(request, authorizer) { + const jwt_secret = new TextEncoder().encode(authorizer.jwt_secret); + const authHeader = request.headers.get('Authorization'); + if (!authHeader || !authHeader.startsWith('Bearer ')) { + throw new AuthError('No token provided or token format is invalid.', 'AUTH_ERROR', 401); + } + const jwt = authHeader.split(' ')[1]; + + try { + const { payload } = await jwtVerify(jwt, jwt_secret, + { + issuer: authorizer.issuer, + audience: authorizer.audience, + } + ); + + return payload; + } catch (error) { + if (error instanceof errors.JOSEAlgNotAllowed) { + throw new AuthError('Algorithm not allowed', error.code, 401); + } else if (error instanceof errors.JWEDecryptionFailed) { + throw new AuthError('Decryption failed', error.code, 401); + } else if (error instanceof errors.JWEInvalid) { + throw new AuthError('Invalid JWE', error.code, 401); + } else if (error instanceof errors.JWTExpired) { + throw new AuthError('Token has expired.', error.code, 401); + } else if (error instanceof errors.JWTClaimValidationFailed) { + throw new AuthError('JWT claim validation failed', error.code, 401); + } else if (error instanceof errors.JWTInvalid) { + throw new AuthError('Invalid JWT', error.code, 401); + } else if (error instanceof errors.JWKSNoMatchingKey) { + throw new AuthError('No matching key found in JWKS.', error.code, 401); + } else if (error instanceof errors.JWKSInvalid) { + throw new AuthError('Invalid JWKS', error.code, 401); + } else if (error instanceof errors.JWKSMultipleMatchingKeys) { + throw new AuthError('Multiple matching keys found in JWKS.', error.code, 401); + } else if (error instanceof errors.JWKSNoMatchingKey) { + throw new AuthError('No matching key in JWKS.', error.code, 401); + } else if (error instanceof errors.JWSInvalid) { + throw new AuthError('Invalid JWS', error.code, 401); + } else if (error instanceof errors.JWSSignatureVerificationFailed) { + throw new AuthError('Signature verification failed', error.code, 401); + } else if (error instanceof Error) { + throw new AuthError('JWT verification failed', 'AUTH_ERROR', 401); + } + // Fallback in case error is not an instance of Error + throw new AuthError('JWT verification failed due to an unexpected error.', 'AUTH_ERROR', 401); + } +} + +export { supabaseEmailOTP, supabasePhoneOTP, supabaseVerifyOTP, supabaseJwtVerify };