@farm.js/supabase 0.1.0-beta.99 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  Supabase integration for Farm.js
4
4
 
5
- Farm.js is currently in beta.
5
+ See [Stability and Support](https://farmjs.dev/docs/stability) for what this package guarantees.
6
6
 
7
7
  ```bash
8
- npm install @farm.js/supabase@beta
8
+ npm install @farm.js/supabase
9
9
  ```
10
10
 
11
11
  See the [Farm.js repository](https://github.com/farming-labs/farm.js) for documentation, examples, and support.
package/dist/index.d.ts CHANGED
@@ -63,7 +63,7 @@ export declare function supabase(input?: SupabaseIntegrationInput): import("@far
63
63
  providers: string[];
64
64
  pages: ResolvedSupabasePages;
65
65
  };
66
- config: import("@farm.js/core").FarmIntegrationConfigDefinition<ResolvedSupabaseEnv, import("@farm.js/core").FarmIntegrationSchema | undefined>;
66
+ config: import("@farm.js/core").FarmIntegrationConfigDefinition<ResolvedSupabaseEnv, import("@farm.js/core").FarmSchema | undefined>;
67
67
  api: {
68
68
  [x: string]: {
69
69
  post: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAC;AACvE,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAC;AAsCvB,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9E,MAAM,MAAM,gCAAgC,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;AAExF,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,kBAAkB,CAAC;IACxC,OAAO,EAAE,gCAAgC,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG,CACxC,OAAO,EAAE,kCAAkC,KACxC,yBAAyB,CAAC;AAE/B,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,2BAA2B,CAAC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,wBAAwB,CAAC;IACjC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC7B;AAED,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,qBAAqB;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAwuBD,wBAAgB,QAAQ,CAAC,KAAK,GAAE,wBAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAuG7B,OAAO,WAAW,6BAA6B;;;;0BA2czC,OAAO,WAAW,6BAA6B;;GAiCpF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAC;AACvE,OAAO,EAGL,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAC;AAsCvB,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9E,MAAM,MAAM,gCAAgC,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;AAExF,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,OAAO,kBAAkB,CAAC;IACxC,OAAO,EAAE,gCAAgC,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG,CACxC,OAAO,EAAE,kCAAkC,KACxC,yBAAyB,CAAC;AAE/B,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,2BAA2B,CAAC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,wBAAwB,CAAC;IACjC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC7B;AAED,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,qBAAqB;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAmwBD,wBAAgB,QAAQ,CAAC,KAAK,GAAE,wBAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAuG7B,OAAO,WAAW,6BAA6B;;;;0BA+czC,OAAO,WAAW,6BAA6B;;GAgDpF"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createServerClient } from "@supabase/ssr";
2
- import { defineIntegration, } from "@farm.js/core";
2
+ import { defineIntegration, forwardIntegrationSetCookies, } from "@farm.js/core";
3
3
  import { describeIntegrationOriginRejection, resolveIntegrationAllowedOrigins, validateIntegrationRequestOrigin, } from "@farm.js/core/integrations";
4
4
  import { api as clientApi } from "@farm.js/core/client";
5
5
  import { createPathInferredClientApi, createDocumentNavigationMatchers, escapeHtml, getOrigin, getReturnTo, integrationConfig, normalizeMatchers, parseCookieHeaderList, resolveAppPath, resolveCallbackSettings, toAbsoluteUrl, withSearchParams, } from "@farm.js/integration-utils";
@@ -592,7 +592,6 @@ function createSupabaseHandler(context, env, instance) {
592
592
  for (const cookie of cookiesToSet) {
593
593
  setCookies.push(serializeCookie(cookie.name, cookie.value, cookie.options));
594
594
  }
595
- context.req.set("supabase:set-cookies", [...setCookies]);
596
595
  },
597
596
  },
598
597
  };
@@ -610,14 +609,35 @@ function createSupabaseHandler(context, env, instance) {
610
609
  setCookies,
611
610
  };
612
611
  }
612
+ async function readSupabaseJsonObject(request) {
613
+ try {
614
+ const body = await request.json();
615
+ if (body && typeof body === "object" && !Array.isArray(body)) {
616
+ return body;
617
+ }
618
+ }
619
+ catch {
620
+ // Report malformed input below without leaking the parser error.
621
+ }
622
+ return Response.json({ error: "Supabase auth request body must be a valid JSON object." }, { status: 400 });
623
+ }
613
624
  async function parseEmailPasswordRequest(request) {
614
625
  const contentType = request.headers.get("content-type") || "";
615
626
  let payload = {};
616
627
  if (contentType.includes("application/json")) {
617
- payload = (await request.json()) || {};
628
+ const parsedBody = await readSupabaseJsonObject(request);
629
+ if (parsedBody instanceof Response)
630
+ return parsedBody;
631
+ payload = parsedBody;
618
632
  }
619
633
  else {
620
- const formData = await request.formData();
634
+ let formData;
635
+ try {
636
+ formData = await request.formData();
637
+ }
638
+ catch {
639
+ return Response.json({ error: "Supabase auth request body must be form data or a JSON object." }, { status: 400 });
640
+ }
621
641
  formData.forEach((value, key) => {
622
642
  payload[key] = value;
623
643
  });
@@ -735,6 +755,8 @@ export function supabase(input = {}) {
735
755
  return rejected;
736
756
  }
737
757
  const parsedRequest = await parseEmailPasswordRequest(request);
758
+ if (parsedRequest instanceof Response)
759
+ return parsedRequest;
738
760
  if (!parsedRequest.ok) {
739
761
  if (clientRequest) {
740
762
  return jsonError(parsedRequest.message, 400);
@@ -891,6 +913,8 @@ export function supabase(input = {}) {
891
913
  return rejected;
892
914
  }
893
915
  const parsedRequest = await parseEmailPasswordRequest(context.request);
916
+ if (parsedRequest instanceof Response)
917
+ return parsedRequest;
894
918
  if (!parsedRequest.ok) {
895
919
  if (clientRequest) {
896
920
  return jsonError(parsedRequest.message, 400);
@@ -1032,7 +1056,10 @@ export function supabase(input = {}) {
1032
1056
  if (request.method === "POST") {
1033
1057
  const contentType = context.request.headers.get("content-type") || "";
1034
1058
  if (contentType.includes("application/json")) {
1035
- const payload = (await context.request.json()) || {};
1059
+ const parsedBody = await readSupabaseJsonObject(context.request);
1060
+ if (parsedBody instanceof Response)
1061
+ return parsedBody;
1062
+ const payload = parsedBody;
1036
1063
  returnTo = getReturnTo(payload.returnTo, returnTo);
1037
1064
  }
1038
1065
  }
@@ -1096,6 +1123,21 @@ export function supabase(input = {}) {
1096
1123
  // the token against Supabase Auth before the route is served.
1097
1124
  const { data, error } = await supabase.auth.getUser();
1098
1125
  if (!error && data?.user) {
1126
+ // getUser() verifies the token with Supabase Auth, and while
1127
+ // doing so can rotate the session server-side (e.g. when the
1128
+ // access token is near expiry), capturing the refreshed
1129
+ // Set-Cookie in setCookies. This branch returns void so the
1130
+ // protected route still renders, which means those cookies
1131
+ // cannot ride on this branch's response — hand them to the
1132
+ // runtime via forwardIntegrationSetCookies so it forwards
1133
+ // them on the downstream response, mirroring the failure
1134
+ // branch's appendSetCookies on its redirect. Without this the
1135
+ // rotated cookie is dropped, the browser keeps the stale
1136
+ // refresh token, and the next protected request logs the user
1137
+ // out via refresh-token reuse detection.
1138
+ if (setCookies.length > 0) {
1139
+ forwardIntegrationSetCookies(context, setCookies);
1140
+ }
1099
1141
  return;
1100
1142
  }
1101
1143
  const redirect = redirectToPage(signInViewPath, context, env.appBaseUrl, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farm.js/supabase",
3
- "version": "0.1.0-beta.99",
3
+ "version": "0.1.0",
4
4
  "description": "Supabase integration for Farm.js",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,13 +31,13 @@
31
31
  "dependencies": {
32
32
  "@supabase/ssr": "^0.9.0",
33
33
  "@supabase/supabase-js": "^2.99.2",
34
- "@farm.js/integration-utils": "0.1.0-beta.99",
35
- "@farm.js/core": "0.1.0-beta.99"
34
+ "@farm.js/core": "0.1.0",
35
+ "@farm.js/integration-utils": "0.1.0"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc",
39
39
  "dev": "tsc --watch",
40
40
  "type-check": "tsc --noEmit",
41
- "test": "echo 'No tests in this package'"
41
+ "test": "pnpm run build && node --test test/*.test.mjs"
42
42
  }
43
43
  }