abckit 0.0.19 → 0.0.20

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.
@@ -1,11 +1,20 @@
1
1
  import type { BetterAuthClientPlugin } from 'better-auth';
2
+ import type { FocusManager, OnlineManager } from 'better-auth/client';
2
3
  interface CapacitorClientOptions {
3
4
  /**
4
5
  * Prefix for storage keys
5
6
  * @default 'better-auth'
6
7
  */
7
8
  storagePrefix?: string;
9
+ /**
10
+ * Prefix(es) for server cookie names to filter
11
+ * Prevents infinite refetching when third-party cookies are set
12
+ * @default 'better-auth'
13
+ */
14
+ cookiePrefix?: string | string[];
8
15
  }
16
+ export declare function setupCapacitorFocusManager(): FocusManager;
17
+ export declare function setupCapacitorOnlineManager(): OnlineManager;
9
18
  /**
10
19
  * Capacitor client plugin for Better Auth
11
20
  * Provides offline-first authentication with persistent storage
@@ -1,4 +1,74 @@
1
1
  import { Preferences } from "@capacitor/preferences";
2
+ import { kFocusManager, kOnlineManager } from "better-auth/client";
3
+ class CapacitorFocusManager {
4
+ listeners = /* @__PURE__ */ new Set();
5
+ unsubscribe;
6
+ subscribe(listener) {
7
+ this.listeners.add(listener);
8
+ return () => {
9
+ this.listeners.delete(listener);
10
+ };
11
+ }
12
+ setFocused(focused) {
13
+ this.listeners.forEach((listener) => listener(focused));
14
+ }
15
+ setup() {
16
+ import("@capacitor/app").then(async ({ App }) => {
17
+ const handle = await App.addListener("appStateChange", (state) => {
18
+ this.setFocused(state.isActive);
19
+ });
20
+ this.unsubscribe = () => handle.remove();
21
+ }).catch(() => {
22
+ });
23
+ return () => {
24
+ this.unsubscribe?.();
25
+ };
26
+ }
27
+ }
28
+ export function setupCapacitorFocusManager() {
29
+ const global = globalThis;
30
+ if (!global[kFocusManager]) {
31
+ global[kFocusManager] = new CapacitorFocusManager();
32
+ }
33
+ return global[kFocusManager];
34
+ }
35
+ class CapacitorOnlineManager {
36
+ listeners = /* @__PURE__ */ new Set();
37
+ isOnline = true;
38
+ unsubscribe;
39
+ subscribe(listener) {
40
+ this.listeners.add(listener);
41
+ return () => {
42
+ this.listeners.delete(listener);
43
+ };
44
+ }
45
+ setOnline(online) {
46
+ this.isOnline = online;
47
+ this.listeners.forEach((listener) => listener(online));
48
+ }
49
+ setup() {
50
+ import("@capacitor/network").then(async ({ Network }) => {
51
+ const handle = await Network.addListener("networkStatusChange", (status) => {
52
+ this.setOnline(status.connected);
53
+ });
54
+ this.unsubscribe = () => handle.remove();
55
+ }).catch(() => {
56
+ this.setOnline(true);
57
+ });
58
+ return () => {
59
+ this.unsubscribe?.();
60
+ };
61
+ }
62
+ }
63
+ export function setupCapacitorOnlineManager() {
64
+ const global = globalThis;
65
+ if (!global[kOnlineManager]) {
66
+ global[kOnlineManager] = new CapacitorOnlineManager();
67
+ }
68
+ return global[kOnlineManager];
69
+ }
70
+ setupCapacitorFocusManager();
71
+ setupCapacitorOnlineManager();
2
72
  function parseSetCookieHeader(header) {
3
73
  const cookieMap = /* @__PURE__ */ new Map();
4
74
  const cookies = splitSetCookieHeader(header);
@@ -87,6 +157,26 @@ function getCookieString(storedCookies) {
87
157
  }
88
158
  return parts.join("; ");
89
159
  }
160
+ function hasBetterAuthCookies(setCookieHeader, cookiePrefix) {
161
+ const cookies = parseSetCookieHeader(setCookieHeader);
162
+ const cookieSuffixes = ["session_token", "session_data"];
163
+ const prefixes = Array.isArray(cookiePrefix) ? cookiePrefix : [cookiePrefix];
164
+ for (const name of cookies.keys()) {
165
+ const nameWithoutSecure = name.startsWith("__Secure-") ? name.slice(9) : name;
166
+ for (const prefix of prefixes) {
167
+ if (prefix) {
168
+ if (nameWithoutSecure.startsWith(prefix))
169
+ return true;
170
+ } else {
171
+ for (const suffix of cookieSuffixes) {
172
+ if (nameWithoutSecure.endsWith(suffix))
173
+ return true;
174
+ }
175
+ }
176
+ }
177
+ }
178
+ return false;
179
+ }
90
180
  function hasSessionCookieChanged(prevCookie, newCookie) {
91
181
  if (!prevCookie)
92
182
  return true;
@@ -114,6 +204,7 @@ function hasSessionCookieChanged(prevCookie, newCookie) {
114
204
  export function capacitorClient(opts) {
115
205
  let store = null;
116
206
  const storagePrefix = opts?.storagePrefix || "better-auth";
207
+ const cookiePrefix = opts?.cookiePrefix || "better-auth";
117
208
  const cookieName = `${storagePrefix}_cookie`;
118
209
  const sessionCacheName = `${storagePrefix}_session`;
119
210
  return {
@@ -170,13 +261,15 @@ export function capacitorClient(opts) {
170
261
  }
171
262
  const setCookie = context.response.headers.get("set-cookie");
172
263
  if (setCookie) {
173
- const prevCookie = (await Preferences.get({ key: cookieName }))?.value;
174
- const newCookie = mergeCookies(setCookie, prevCookie ?? void 0);
175
- if (hasSessionCookieChanged(prevCookie ?? null, newCookie)) {
176
- await Preferences.set({ key: cookieName, value: newCookie });
177
- store?.notify("$sessionSignal");
178
- } else {
179
- await Preferences.set({ key: cookieName, value: newCookie });
264
+ if (hasBetterAuthCookies(setCookie, cookiePrefix)) {
265
+ const prevCookie = (await Preferences.get({ key: cookieName }))?.value;
266
+ const newCookie = mergeCookies(setCookie, prevCookie ?? void 0);
267
+ if (hasSessionCookieChanged(prevCookie ?? null, newCookie)) {
268
+ await Preferences.set({ key: cookieName, value: newCookie });
269
+ store?.notify("$sessionSignal");
270
+ } else {
271
+ await Preferences.set({ key: cookieName, value: newCookie });
272
+ }
180
273
  }
181
274
  }
182
275
  if (context.request.url.toString().includes("/get-session")) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "abckit",
3
3
  "type": "module",
4
- "version": "0.0.19",
4
+ "version": "0.0.20",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {
@@ -56,7 +56,9 @@
56
56
  "release": "pnpm publish --no-git-checks --access public"
57
57
  },
58
58
  "dependencies": {
59
+ "@capacitor/app": "^7.1.1",
59
60
  "@capacitor/core": "^7.0.1",
61
+ "@capacitor/network": "^7.0.3",
60
62
  "@capacitor/preferences": "^7.0.1",
61
63
  "@graphql-tools/utils": "^10.11.0",
62
64
  "@nuxt/icon": "^2.1.0",