@anythink-cloud/sdk 0.1.1 → 0.2.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/dist/index.d.mts CHANGED
@@ -30,17 +30,38 @@ interface Session {
30
30
  expires_in: number;
31
31
  expires_at: number;
32
32
  }
33
+ /**
34
+ * Cookie storage configuration options
35
+ */
36
+ interface CookieStorageConfig {
37
+ /**
38
+ * Cookie name (default: 'anythink_auth_session')
39
+ */
40
+ name?: string;
41
+ /**
42
+ * Cookie domain (optional)
43
+ */
44
+ domain?: string;
45
+ /**
46
+ * Cookie path (default: '/')
47
+ */
48
+ path?: string;
49
+ /**
50
+ * Whether to use Secure flag (HTTPS only, default: true in production)
51
+ */
52
+ secure?: boolean;
53
+ /**
54
+ * SameSite attribute (default: 'lax')
55
+ */
56
+ sameSite?: "strict" | "lax" | "none";
57
+ }
33
58
  /**
34
59
  * Configuration for the auth client
35
60
  */
36
61
  interface AuthConfig {
37
62
  instanceUrl: string;
38
63
  orgId: number;
39
- tokenEndpoint?: string;
40
- refreshEndpoint?: string;
41
- changePasswordEndpoint?: string;
42
- storageKey?: string;
43
- onSignOut?: () => void;
64
+ cookieStorage?: CookieStorageConfig;
44
65
  }
45
66
  /**
46
67
  * Sign in response
@@ -61,6 +82,37 @@ interface RefreshResponse {
61
82
  error: Error | null;
62
83
  }
63
84
 
85
+ /**
86
+ * Cookie storage adapter that implements the same interface as localStorage
87
+ * for use with Zustand's persist middleware.
88
+ */
89
+ interface CookieStorageOptions {
90
+ /**
91
+ * Cookie name/key
92
+ */
93
+ name: string;
94
+ /**
95
+ * Cookie domain (optional)
96
+ */
97
+ domain?: string;
98
+ /**
99
+ * Cookie path (default: '/')
100
+ */
101
+ path?: string;
102
+ /**
103
+ * Whether to use Secure flag (HTTPS only, default: true in production)
104
+ */
105
+ secure?: boolean;
106
+ /**
107
+ * SameSite attribute (default: 'lax')
108
+ */
109
+ sameSite?: "strict" | "lax" | "none";
110
+ /**
111
+ * Maximum age in seconds (optional, for expiration)
112
+ */
113
+ maxAge?: number;
114
+ }
115
+
64
116
  interface AuthState {
65
117
  session: Session | null;
66
118
  isLoading: boolean;
@@ -72,10 +124,12 @@ interface AuthState {
72
124
  setError: (error: Error | null) => void;
73
125
  }
74
126
  /**
75
- * Creates the auth store with persistence
76
- * @param storageKey - Key for localStorage persistence
127
+ * Creates the auth store with cookie-based persistence
128
+ * Always uses cookies with default values, never localStorage
129
+ * @param storageKey - Key for cookie storage (cookie name)
130
+ * @param cookieOptions - Optional cookie configuration options to override defaults
77
131
  */
78
- declare const createAuthStore: (storageKey?: string) => zustand.UseBoundStore<Omit<zustand.StoreApi<AuthState>, "setState" | "persist"> & {
132
+ declare const createAuthStore: (cookieOptions?: CookieStorageOptions) => zustand.UseBoundStore<Omit<zustand.StoreApi<AuthState>, "setState" | "persist"> & {
79
133
  setState(partial: AuthState | Partial<AuthState> | ((state: AuthState) => AuthState | Partial<AuthState>), replace?: false | undefined): unknown;
80
134
  setState(state: AuthState | ((state: AuthState) => AuthState), replace: true): unknown;
81
135
  persist: {
@@ -95,20 +149,8 @@ declare const createAuthStore: (storageKey?: string) => zustand.UseBoundStore<Om
95
149
  declare class AuthClient {
96
150
  private store;
97
151
  private config;
98
- private onSessionChanged?;
99
152
  private axiosClient;
100
- constructor(config: AuthConfig & {
101
- onSessionChanged?: (session: Session | null) => void;
102
- });
103
- /**
104
- * Set the onSessionChanged handler.
105
- * @param handler Callback fired whenever the session changes
106
- */
107
- setOnSessionChanged(handler: ((session: Session | null) => void) | undefined): void;
108
- /**
109
- * Internal helper to call the session-changed handler, if present.
110
- */
111
- private _callSessionChanged;
153
+ constructor(config: AuthConfig);
112
154
  /**
113
155
  * Sign in with email and password
114
156
  * @param email User email
@@ -166,9 +208,11 @@ declare class AuthClient {
166
208
  }>;
167
209
  /**
168
210
  * Sign out and clear session
211
+ * Invalidates the refresh token on the server and clears local session
212
+ * @returns Error object or null if successful
169
213
  */
170
214
  signOut(): Promise<{
171
- error: null;
215
+ error: Error | null;
172
216
  }>;
173
217
  /**
174
218
  * Get the current access token
@@ -230,11 +274,4 @@ declare class AuthenticatedBaseService {
230
274
  getClient(): AxiosInstance;
231
275
  }
232
276
 
233
- /**
234
- * Anythink SDK
235
- *
236
- * A reusable Typescript SDK for the Anythink platform.
237
- */
238
- declare const version = "0.1.1";
239
-
240
- export { AuthClient, type AuthConfig, AuthenticatedBaseService, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore, version };
277
+ export { AuthClient, type AuthConfig, AuthenticatedBaseService, type CookieStorageConfig, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore };
package/dist/index.d.ts CHANGED
@@ -30,17 +30,38 @@ interface Session {
30
30
  expires_in: number;
31
31
  expires_at: number;
32
32
  }
33
+ /**
34
+ * Cookie storage configuration options
35
+ */
36
+ interface CookieStorageConfig {
37
+ /**
38
+ * Cookie name (default: 'anythink_auth_session')
39
+ */
40
+ name?: string;
41
+ /**
42
+ * Cookie domain (optional)
43
+ */
44
+ domain?: string;
45
+ /**
46
+ * Cookie path (default: '/')
47
+ */
48
+ path?: string;
49
+ /**
50
+ * Whether to use Secure flag (HTTPS only, default: true in production)
51
+ */
52
+ secure?: boolean;
53
+ /**
54
+ * SameSite attribute (default: 'lax')
55
+ */
56
+ sameSite?: "strict" | "lax" | "none";
57
+ }
33
58
  /**
34
59
  * Configuration for the auth client
35
60
  */
36
61
  interface AuthConfig {
37
62
  instanceUrl: string;
38
63
  orgId: number;
39
- tokenEndpoint?: string;
40
- refreshEndpoint?: string;
41
- changePasswordEndpoint?: string;
42
- storageKey?: string;
43
- onSignOut?: () => void;
64
+ cookieStorage?: CookieStorageConfig;
44
65
  }
45
66
  /**
46
67
  * Sign in response
@@ -61,6 +82,37 @@ interface RefreshResponse {
61
82
  error: Error | null;
62
83
  }
63
84
 
85
+ /**
86
+ * Cookie storage adapter that implements the same interface as localStorage
87
+ * for use with Zustand's persist middleware.
88
+ */
89
+ interface CookieStorageOptions {
90
+ /**
91
+ * Cookie name/key
92
+ */
93
+ name: string;
94
+ /**
95
+ * Cookie domain (optional)
96
+ */
97
+ domain?: string;
98
+ /**
99
+ * Cookie path (default: '/')
100
+ */
101
+ path?: string;
102
+ /**
103
+ * Whether to use Secure flag (HTTPS only, default: true in production)
104
+ */
105
+ secure?: boolean;
106
+ /**
107
+ * SameSite attribute (default: 'lax')
108
+ */
109
+ sameSite?: "strict" | "lax" | "none";
110
+ /**
111
+ * Maximum age in seconds (optional, for expiration)
112
+ */
113
+ maxAge?: number;
114
+ }
115
+
64
116
  interface AuthState {
65
117
  session: Session | null;
66
118
  isLoading: boolean;
@@ -72,10 +124,12 @@ interface AuthState {
72
124
  setError: (error: Error | null) => void;
73
125
  }
74
126
  /**
75
- * Creates the auth store with persistence
76
- * @param storageKey - Key for localStorage persistence
127
+ * Creates the auth store with cookie-based persistence
128
+ * Always uses cookies with default values, never localStorage
129
+ * @param storageKey - Key for cookie storage (cookie name)
130
+ * @param cookieOptions - Optional cookie configuration options to override defaults
77
131
  */
78
- declare const createAuthStore: (storageKey?: string) => zustand.UseBoundStore<Omit<zustand.StoreApi<AuthState>, "setState" | "persist"> & {
132
+ declare const createAuthStore: (cookieOptions?: CookieStorageOptions) => zustand.UseBoundStore<Omit<zustand.StoreApi<AuthState>, "setState" | "persist"> & {
79
133
  setState(partial: AuthState | Partial<AuthState> | ((state: AuthState) => AuthState | Partial<AuthState>), replace?: false | undefined): unknown;
80
134
  setState(state: AuthState | ((state: AuthState) => AuthState), replace: true): unknown;
81
135
  persist: {
@@ -95,20 +149,8 @@ declare const createAuthStore: (storageKey?: string) => zustand.UseBoundStore<Om
95
149
  declare class AuthClient {
96
150
  private store;
97
151
  private config;
98
- private onSessionChanged?;
99
152
  private axiosClient;
100
- constructor(config: AuthConfig & {
101
- onSessionChanged?: (session: Session | null) => void;
102
- });
103
- /**
104
- * Set the onSessionChanged handler.
105
- * @param handler Callback fired whenever the session changes
106
- */
107
- setOnSessionChanged(handler: ((session: Session | null) => void) | undefined): void;
108
- /**
109
- * Internal helper to call the session-changed handler, if present.
110
- */
111
- private _callSessionChanged;
153
+ constructor(config: AuthConfig);
112
154
  /**
113
155
  * Sign in with email and password
114
156
  * @param email User email
@@ -166,9 +208,11 @@ declare class AuthClient {
166
208
  }>;
167
209
  /**
168
210
  * Sign out and clear session
211
+ * Invalidates the refresh token on the server and clears local session
212
+ * @returns Error object or null if successful
169
213
  */
170
214
  signOut(): Promise<{
171
- error: null;
215
+ error: Error | null;
172
216
  }>;
173
217
  /**
174
218
  * Get the current access token
@@ -230,11 +274,4 @@ declare class AuthenticatedBaseService {
230
274
  getClient(): AxiosInstance;
231
275
  }
232
276
 
233
- /**
234
- * Anythink SDK
235
- *
236
- * A reusable Typescript SDK for the Anythink platform.
237
- */
238
- declare const version = "0.1.1";
239
-
240
- export { AuthClient, type AuthConfig, AuthenticatedBaseService, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore, version };
277
+ export { AuthClient, type AuthConfig, AuthenticatedBaseService, type CookieStorageConfig, type RefreshResponse, type Session, type SignInResponse, type TokenPair, type User, createAuthStore };
package/dist/index.js CHANGED
@@ -9,7 +9,106 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
9
  var axios__default = /*#__PURE__*/_interopDefault(axios);
10
10
 
11
11
  // src/auth/client.ts
12
- var createAuthStore = (storageKey = "anythink_auth_session") => {
12
+
13
+ // src/auth/cookieStorage.ts
14
+ function createCookieStorage(options) {
15
+ const {
16
+ domain,
17
+ path = "/",
18
+ secure = typeof window !== "undefined" && window.location.protocol === "https:",
19
+ sameSite = "lax"
20
+ } = options;
21
+ function getCookie(cookieName) {
22
+ if (typeof document === "undefined") {
23
+ return null;
24
+ }
25
+ const nameEQ = cookieName + "=";
26
+ const cookies = document.cookie.split(";");
27
+ for (let i = 0; i < cookies.length; i++) {
28
+ let cookie = cookies[i];
29
+ while (cookie.charAt(0) === " ") {
30
+ cookie = cookie.substring(1, cookie.length);
31
+ }
32
+ if (cookie.indexOf(nameEQ) === 0) {
33
+ return decodeURIComponent(
34
+ cookie.substring(nameEQ.length, cookie.length)
35
+ );
36
+ }
37
+ }
38
+ return null;
39
+ }
40
+ function setCookie(cookieName, value, cookieOptions) {
41
+ if (typeof document === "undefined") {
42
+ return;
43
+ }
44
+ let cookieString = `${cookieName}=${encodeURIComponent(value)}`;
45
+ if (cookieOptions?.maxAge) {
46
+ cookieString += `; max-age=${cookieOptions.maxAge}`;
47
+ } else if (cookieOptions?.expires) {
48
+ cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;
49
+ }
50
+ cookieString += `; path=${path}`;
51
+ if (domain) {
52
+ cookieString += `; domain=${domain}`;
53
+ }
54
+ if (secure) {
55
+ cookieString += "; secure";
56
+ }
57
+ cookieString += `; samesite=${sameSite}`;
58
+ document.cookie = cookieString;
59
+ }
60
+ function removeCookie(cookieName) {
61
+ if (typeof document === "undefined") {
62
+ return;
63
+ }
64
+ let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;
65
+ if (domain) {
66
+ cookieString += `; domain=${domain}`;
67
+ }
68
+ document.cookie = cookieString;
69
+ }
70
+ return {
71
+ getItem: (key) => {
72
+ try {
73
+ const value = getCookie(key);
74
+ return value;
75
+ } catch (error) {
76
+ console.warn("Failed to get cookie:", error);
77
+ return null;
78
+ }
79
+ },
80
+ setItem: (key, value) => {
81
+ try {
82
+ let maxAge = options.maxAge;
83
+ try {
84
+ const parsed = JSON.parse(value);
85
+ if (parsed?.session?.expires_at) {
86
+ const expiresAt = parsed.session.expires_at;
87
+ const now = Math.floor(Date.now() / 1e3);
88
+ const remainingSeconds = expiresAt - now;
89
+ if (remainingSeconds > 0) {
90
+ maxAge = remainingSeconds;
91
+ }
92
+ }
93
+ } catch {
94
+ }
95
+ setCookie(key, value, maxAge ? { maxAge } : void 0);
96
+ } catch (error) {
97
+ console.warn("Failed to set cookie:", error);
98
+ }
99
+ },
100
+ removeItem: (key) => {
101
+ try {
102
+ removeCookie(key);
103
+ } catch (error) {
104
+ console.warn("Failed to remove cookie:", error);
105
+ }
106
+ }
107
+ };
108
+ }
109
+
110
+ // src/auth/store.ts
111
+ var createAuthStore = (cookieOptions) => {
13
112
  return zustand.create()(
14
113
  middleware.persist(
15
114
  (set) => ({
@@ -33,18 +132,16 @@ var createAuthStore = (storageKey = "anythink_auth_session") => {
33
132
  }
34
133
  }),
35
134
  {
36
- name: storageKey,
135
+ name: cookieOptions?.name ?? "anythink_auth_session",
37
136
  storage: middleware.createJSONStorage(() => {
38
- if (typeof globalThis !== "undefined" && "localStorage" in globalThis) {
39
- return globalThis.localStorage;
40
- }
41
- return {
42
- getItem: () => null,
43
- setItem: () => {
44
- },
45
- removeItem: () => {
46
- }
47
- };
137
+ return createCookieStorage({
138
+ name: cookieOptions?.name ?? "anythink_auth_session",
139
+ path: "/",
140
+ secure: typeof window !== "undefined" && window.location.protocol === "https:",
141
+ sameSite: "lax",
142
+ ...cookieOptions
143
+ // User-provided options override defaults
144
+ });
48
145
  }),
49
146
  // Only persist the session, not loading/error states
50
147
  partialize: (state) => ({ session: state.session })
@@ -56,45 +153,20 @@ var createAuthStore = (storageKey = "anythink_auth_session") => {
56
153
  // src/auth/client.ts
57
154
  var AuthClient = class {
58
155
  constructor(config) {
59
- this.config = {
60
- tokenEndpoint: "/auth/v1/token",
61
- refreshEndpoint: "/auth/v1/refresh",
62
- changePasswordEndpoint: "/users/me/password",
63
- storageKey: "anythink_auth_session",
64
- onSignOut: () => {
65
- return;
66
- },
67
- ...config
68
- };
69
- this.store = createAuthStore(this.config.storageKey);
156
+ this.config = config;
157
+ this.store = createAuthStore({
158
+ name: this.config.cookieStorage?.name ?? "anythink_auth_session",
159
+ domain: this.config.cookieStorage?.domain,
160
+ path: this.config.cookieStorage?.path,
161
+ secure: this.config.cookieStorage?.secure,
162
+ sameSite: this.config.cookieStorage?.sameSite
163
+ });
70
164
  this.axiosClient = axios__default.default.create({
71
165
  baseURL: this.config.instanceUrl,
72
166
  headers: {
73
167
  "Content-Type": "application/json"
74
168
  }
75
169
  });
76
- if (typeof config.onSessionChanged === "function") {
77
- this.onSessionChanged = config.onSessionChanged;
78
- }
79
- }
80
- /**
81
- * Set the onSessionChanged handler.
82
- * @param handler Callback fired whenever the session changes
83
- */
84
- setOnSessionChanged(handler) {
85
- this.onSessionChanged = handler;
86
- }
87
- /**
88
- * Internal helper to call the session-changed handler, if present.
89
- */
90
- _callSessionChanged(session) {
91
- if (typeof this.onSessionChanged === "function") {
92
- try {
93
- this.onSessionChanged(session);
94
- } catch (e) {
95
- console.warn("onSessionChanged threw:", e);
96
- }
97
- }
98
170
  }
99
171
  /**
100
172
  * Sign in with email and password
@@ -109,7 +181,7 @@ var AuthClient = class {
109
181
  this.store.getState().clearError();
110
182
  const params = orgId ? { org_id: orgId.toString() } : void 0;
111
183
  const response = await this.axiosClient.post(
112
- this.config.tokenEndpoint,
184
+ "/auth/v1/token",
113
185
  { email, password },
114
186
  { params }
115
187
  );
@@ -121,7 +193,6 @@ var AuthClient = class {
121
193
  expires_at: Math.floor(Date.now() / 1e3) + tokenPair.expires_in
122
194
  };
123
195
  this.store.getState().setSession(session);
124
- this._callSessionChanged(session);
125
196
  this.store.getState().setLoading(false);
126
197
  return { data: { session }, error: null };
127
198
  } catch (error) {
@@ -135,7 +206,6 @@ var AuthClient = class {
135
206
  this.store.getState().setError(authError);
136
207
  this.store.getState().setLoading(false);
137
208
  this.store.getState().setSession(null);
138
- this._callSessionChanged(null);
139
209
  return {
140
210
  data: { session: null },
141
211
  error: authError
@@ -191,7 +261,7 @@ var AuthClient = class {
191
261
  this.store.getState().setLoading(true);
192
262
  this.store.getState().clearError();
193
263
  const response = await this.axiosClient.post(
194
- this.config.refreshEndpoint,
264
+ "/auth/v1/refresh",
195
265
  { token: session.refresh_token }
196
266
  );
197
267
  const tokenPair = response.data;
@@ -202,12 +272,10 @@ var AuthClient = class {
202
272
  expires_at: Math.floor(Date.now() / 1e3) + tokenPair.expires_in
203
273
  };
204
274
  this.store.getState().setSession(newSession);
205
- this._callSessionChanged(newSession);
206
275
  this.store.getState().setLoading(false);
207
276
  return { data: { session: newSession }, error: null };
208
277
  } catch (error) {
209
278
  this.store.getState().setSession(null);
210
- this._callSessionChanged(null);
211
279
  this.store.getState().setLoading(false);
212
280
  let authError;
213
281
  if (error instanceof axios.AxiosError) {
@@ -253,10 +321,8 @@ var AuthClient = class {
253
321
  expires_at: Math.floor(Date.now() / 1e3) + expires_in
254
322
  };
255
323
  this.store.getState().setSession(session);
256
- this._callSessionChanged(session);
257
324
  return { error: null };
258
325
  } catch (error) {
259
- this._callSessionChanged(null);
260
326
  return {
261
327
  error: error instanceof Error ? error : new Error("Failed to set session")
262
328
  };
@@ -275,7 +341,7 @@ var AuthClient = class {
275
341
  throw new Error("No access token found");
276
342
  }
277
343
  await this.axiosClient.post(
278
- this.config.changePasswordEndpoint,
344
+ "/users/me/password",
279
345
  {
280
346
  current_password: currentPassword,
281
347
  new_password: newPassword
@@ -302,12 +368,28 @@ var AuthClient = class {
302
368
  }
303
369
  /**
304
370
  * Sign out and clear session
371
+ * Invalidates the refresh token on the server and clears local session
372
+ * @returns Error object or null if successful
305
373
  */
306
374
  async signOut() {
375
+ const refreshToken = this.getRefreshToken();
307
376
  this.store.getState().signOut();
308
- this._callSessionChanged(null);
309
- if (this.config.onSignOut) {
310
- this.config.onSignOut();
377
+ if (refreshToken) {
378
+ try {
379
+ await this.axiosClient.post("/auth/v1/logout", {
380
+ token: refreshToken
381
+ });
382
+ } catch (error) {
383
+ if (error instanceof axios.AxiosError) {
384
+ if (error.response?.status !== 401 && error.response?.status !== 404) {
385
+ console.warn(
386
+ "Failed to invalidate refresh token on server:",
387
+ error.message
388
+ );
389
+ }
390
+ }
391
+ return { error: null };
392
+ }
311
393
  }
312
394
  return { error: null };
313
395
  }
@@ -470,12 +552,8 @@ var AuthenticatedBaseService = class {
470
552
  }
471
553
  };
472
554
 
473
- // src/index.ts
474
- var version = "0.1.1";
475
-
476
555
  exports.AuthClient = AuthClient;
477
556
  exports.AuthenticatedBaseService = AuthenticatedBaseService;
478
557
  exports.createAuthStore = createAuthStore;
479
- exports.version = version;
480
558
  //# sourceMappingURL=index.js.map
481
559
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth/store.ts","../src/auth/client.ts","../src/services/AuthenticatedBaseService.ts","../src/index.ts"],"names":["create","persist","createJSONStorage","axios","AxiosError"],"mappings":"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","file":"index.js","sourcesContent":["import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session } from \"@/types/auth\";\n\ninterface AuthState {\n session: Session | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with persistence\n * @param storageKey - Key for localStorage persistence\n */\nexport const createAuthStore = (\n storageKey: string = \"anythink_auth_session\"\n) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n signOut: () => {\n set({ session: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: storageKey,\n storage: createJSONStorage(() => {\n // Use localStorage for persistence\n if (\n typeof globalThis !== \"undefined\" &&\n \"localStorage\" in globalThis\n ) {\n return (globalThis as any).localStorage;\n }\n // Fallback for SSR\n return {\n getItem: () => null,\n setItem: () => {},\n removeItem: () => {},\n };\n }),\n // Only persist the session, not loading/error states\n partialize: (state: AuthState) => ({ session: state.session }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: Required<AuthConfig>;\n private onSessionChanged?: (session: Session | null) => void;\n private axiosClient: AxiosInstance;\n\n constructor(\n config: AuthConfig & {\n onSessionChanged?: (session: Session | null) => void;\n }\n ) {\n this.config = {\n tokenEndpoint: \"/auth/v1/token\",\n refreshEndpoint: \"/auth/v1/refresh\",\n changePasswordEndpoint: \"/users/me/password\",\n storageKey: \"anythink_auth_session\",\n onSignOut: () => {\n return;\n },\n ...config,\n };\n\n this.store = createAuthStore(this.config.storageKey);\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (typeof config.onSessionChanged === \"function\") {\n this.onSessionChanged = config.onSessionChanged;\n }\n }\n\n /**\n * Set the onSessionChanged handler.\n * @param handler Callback fired whenever the session changes\n */\n setOnSessionChanged(\n handler: ((session: Session | null) => void) | undefined\n ) {\n this.onSessionChanged = handler;\n }\n\n /**\n * Internal helper to call the session-changed handler, if present.\n */\n private _callSessionChanged(session: Session | null) {\n if (typeof this.onSessionChanged === \"function\") {\n try {\n this.onSessionChanged(session);\n } catch (e) {\n // Avoid throwing in userland\n console.warn(\"onSessionChanged threw:\", e);\n }\n }\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n this.config.tokenEndpoint,\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this._callSessionChanged(session); // Call hook here\n this.store.getState().setLoading(false);\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n this._callSessionChanged(null); // Call hook for failed sign in\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\"/auth/v1/register\", {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n });\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n this.config.refreshEndpoint,\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this._callSessionChanged(newSession); // Call here\n this.store.getState().setLoading(false);\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this._callSessionChanged(null); // Call hook here on null-out\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n\n // Check if session is expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (\n session &&\n session.expires_at &&\n Date.now() >= session.expires_at * 1000\n ) {\n // Session expired, return null\n // The caller should handle refresh if needed\n return { data: { session: null } };\n }\n\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n this._callSessionChanged(session); // Call here\n return { error: null };\n } catch (error) {\n this._callSessionChanged(null); // Defensive, though only on explicit error\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n this.config.changePasswordEndpoint,\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n */\n async signOut(): Promise<{ error: null }> {\n this.store.getState().signOut();\n this._callSessionChanged(null); // Call on sign out\n if (this.config.onSignOut) {\n this.config.onSignOut();\n }\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return null;\n }\n\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n\n // Response interceptor: Handle token refresh on 401\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as AxiosRequestConfig & {\n _retry?: boolean;\n };\n\n // If the error is 401 (Unauthorized) and we haven't already tried to refresh\n if (\n error.response?.status === 401 &&\n originalRequest &&\n !originalRequest._retry\n ) {\n originalRequest._retry = true;\n\n try {\n // Try to refresh the token\n const { data, error: refreshError } =\n await this.authClient.refreshSession();\n\n if (data.session && !refreshError) {\n // Retry the original request with the new token\n const token = this.authClient.getAccessToken();\n if (token) {\n if (!originalRequest.headers) {\n originalRequest.headers = {};\n }\n originalRequest.headers.Authorization = `Bearer ${token}`;\n }\n return this.client(originalRequest);\n } else {\n // Refresh failed, sign out\n await this.authClient.signOut();\n }\n } catch (refreshError) {\n // Refresh failed, sign out\n await this.authClient.signOut();\n return Promise.reject(refreshError);\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n","/**\n * Anythink SDK\n *\n * A reusable Typescript SDK for the Anythink platform.\n */\n\n// Version\nexport const version = \"0.1.1\";\n\n// Auth exports\nexport { AuthClient } from \"@/auth/client\";\nexport { createAuthStore } from \"@/auth/store\";\n\n// Service exports\nexport { AuthenticatedBaseService } from \"@/services/AuthenticatedBaseService\";\n\n// Type exports\nexport type {\n AuthConfig,\n User,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n} from \"@/types/auth\";\n"]}
1
+ {"version":3,"sources":["../src/auth/cookieStorage.ts","../src/auth/store.ts","../src/auth/client.ts","../src/services/AuthenticatedBaseService.ts"],"names":["create","persist","createJSONStorage","axios","AxiosError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Cookie storage adapter that implements the same interface as localStorage\n * for use with Zustand's persist middleware.\n */\nexport interface CookieStorageOptions {\n /**\n * Cookie name/key\n */\n name: string;\n /**\n * Cookie domain (optional)\n */\n domain?: string;\n /**\n * Cookie path (default: '/')\n */\n path?: string;\n /**\n * Whether to use Secure flag (HTTPS only, default: true in production)\n */\n secure?: boolean;\n /**\n * SameSite attribute (default: 'lax')\n */\n sameSite?: \"strict\" | \"lax\" | \"none\";\n /**\n * Maximum age in seconds (optional, for expiration)\n */\n maxAge?: number;\n}\n\n/**\n * Creates a cookie storage adapter compatible with Zustand's persist middleware\n */\nexport function createCookieStorage(options: CookieStorageOptions) {\n const {\n domain,\n path = \"/\",\n secure = typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite = \"lax\",\n } = options;\n\n /**\n * Get a cookie value by name\n */\n function getCookie(cookieName: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const nameEQ = cookieName + \"=\";\n const cookies = document.cookie.split(\";\");\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === \" \") {\n cookie = cookie.substring(1, cookie.length);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(\n cookie.substring(nameEQ.length, cookie.length)\n );\n }\n }\n return null;\n }\n\n /**\n * Set a cookie value\n */\n function setCookie(\n cookieName: string,\n value: string,\n cookieOptions?: {\n maxAge?: number;\n expires?: Date;\n }\n ): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=${encodeURIComponent(value)}`;\n\n if (cookieOptions?.maxAge) {\n cookieString += `; max-age=${cookieOptions.maxAge}`;\n } else if (cookieOptions?.expires) {\n cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n if (secure) {\n cookieString += \"; secure\";\n }\n\n cookieString += `; samesite=${sameSite}`;\n\n document.cookie = cookieString;\n }\n\n /**\n * Remove a cookie\n */\n function removeCookie(cookieName: string): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n }\n\n return {\n getItem: (key: string): string | null => {\n try {\n const value = getCookie(key);\n return value;\n } catch (error) {\n console.warn(\"Failed to get cookie:\", error);\n return null;\n }\n },\n\n setItem: (key: string, value: string): void => {\n try {\n // Try to parse the value as JSON to extract session expiration\n let maxAge: number | undefined = options.maxAge;\n\n try {\n const parsed = JSON.parse(value);\n // If the stored value contains a session with expires_at, calculate maxAge\n if (parsed?.session?.expires_at) {\n const expiresAt = parsed.session.expires_at;\n const now = Math.floor(Date.now() / 1000);\n const remainingSeconds = expiresAt - now;\n // Only set maxAge if it's positive (not expired)\n if (remainingSeconds > 0) {\n maxAge = remainingSeconds;\n }\n }\n } catch {\n // If parsing fails, value is not JSON, use default maxAge if provided\n }\n\n setCookie(key, value, maxAge ? { maxAge } : undefined);\n } catch (error) {\n console.warn(\"Failed to set cookie:\", error);\n }\n },\n\n removeItem: (key: string): void => {\n try {\n removeCookie(key);\n } catch (error) {\n console.warn(\"Failed to remove cookie:\", error);\n }\n },\n };\n}\n","import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session } from \"@/types/auth\";\nimport {\n createCookieStorage,\n type CookieStorageOptions,\n} from \"@/auth/cookieStorage\";\n\ninterface AuthState {\n session: Session | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with cookie-based persistence\n * Always uses cookies with default values, never localStorage\n * @param storageKey - Key for cookie storage (cookie name)\n * @param cookieOptions - Optional cookie configuration options to override defaults\n */\nexport const createAuthStore = (cookieOptions?: CookieStorageOptions) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n signOut: () => {\n set({ session: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n storage: createJSONStorage(() => {\n // Always use cookie storage with defaults\n // Defaults: path='/', secure=true (if HTTPS), sameSite='lax'\n return createCookieStorage({\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n path: \"/\",\n secure:\n typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite: \"lax\",\n ...cookieOptions, // User-provided options override defaults\n });\n }),\n // Only persist the session, not loading/error states\n partialize: (state: AuthState) => ({ session: state.session }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: AuthConfig;\n private axiosClient: AxiosInstance;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.store = createAuthStore({\n name: this.config.cookieStorage?.name ?? \"anythink_auth_session\",\n domain: this.config.cookieStorage?.domain,\n path: this.config.cookieStorage?.path,\n secure: this.config.cookieStorage?.secure,\n sameSite: this.config.cookieStorage?.sameSite,\n });\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n \"/auth/v1/token\",\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this.store.getState().setLoading(false);\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\"/auth/v1/register\", {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n });\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n \"/auth/v1/refresh\",\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this.store.getState().setLoading(false);\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n\n // Check if session is expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (\n session &&\n session.expires_at &&\n Date.now() >= session.expires_at * 1000\n ) {\n // Session expired, return null\n // The caller should handle refresh if needed\n return { data: { session: null } };\n }\n\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n return { error: null };\n } catch (error) {\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n \"/users/me/password\",\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n * Invalidates the refresh token on the server and clears local session\n * @returns Error object or null if successful\n */\n async signOut(): Promise<{ error: Error | null }> {\n const refreshToken = this.getRefreshToken();\n\n // Always clear local session first\n this.store.getState().signOut();\n\n // If we have a refresh token, try to invalidate it on the server\n // This is best practice for security - prevents token reuse\n if (refreshToken) {\n try {\n await this.axiosClient.post(\"/auth/v1/logout\", {\n token: refreshToken,\n });\n } catch (error) {\n // If the API call fails, we've already cleared local session\n // Log the error but don't fail the sign out operation\n // The token may already be invalid or expired, which is fine\n if (error instanceof AxiosError) {\n // Only log if it's not a 401/404 (token already invalid/not found)\n if (\n error.response?.status !== 401 &&\n error.response?.status !== 404\n ) {\n console.warn(\n \"Failed to invalidate refresh token on server:\",\n error.message\n );\n }\n }\n // Return null error - sign out succeeded locally even if server call failed\n return { error: null };\n }\n }\n\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return null;\n }\n\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n\n // Response interceptor: Handle token refresh on 401\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as AxiosRequestConfig & {\n _retry?: boolean;\n };\n\n // If the error is 401 (Unauthorized) and we haven't already tried to refresh\n if (\n error.response?.status === 401 &&\n originalRequest &&\n !originalRequest._retry\n ) {\n originalRequest._retry = true;\n\n try {\n // Try to refresh the token\n const { data, error: refreshError } =\n await this.authClient.refreshSession();\n\n if (data.session && !refreshError) {\n // Retry the original request with the new token\n const token = this.authClient.getAccessToken();\n if (token) {\n if (!originalRequest.headers) {\n originalRequest.headers = {};\n }\n originalRequest.headers.Authorization = `Bearer ${token}`;\n }\n return this.client(originalRequest);\n } else {\n // Refresh failed, sign out\n await this.authClient.signOut();\n }\n } catch (refreshError) {\n // Refresh failed, sign out\n await this.authClient.signOut();\n return Promise.reject(refreshError);\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n"]}
package/dist/index.mjs CHANGED
@@ -3,7 +3,106 @@ import { create } from 'zustand';
3
3
  import { persist, createJSONStorage } from 'zustand/middleware';
4
4
 
5
5
  // src/auth/client.ts
6
- var createAuthStore = (storageKey = "anythink_auth_session") => {
6
+
7
+ // src/auth/cookieStorage.ts
8
+ function createCookieStorage(options) {
9
+ const {
10
+ domain,
11
+ path = "/",
12
+ secure = typeof window !== "undefined" && window.location.protocol === "https:",
13
+ sameSite = "lax"
14
+ } = options;
15
+ function getCookie(cookieName) {
16
+ if (typeof document === "undefined") {
17
+ return null;
18
+ }
19
+ const nameEQ = cookieName + "=";
20
+ const cookies = document.cookie.split(";");
21
+ for (let i = 0; i < cookies.length; i++) {
22
+ let cookie = cookies[i];
23
+ while (cookie.charAt(0) === " ") {
24
+ cookie = cookie.substring(1, cookie.length);
25
+ }
26
+ if (cookie.indexOf(nameEQ) === 0) {
27
+ return decodeURIComponent(
28
+ cookie.substring(nameEQ.length, cookie.length)
29
+ );
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ function setCookie(cookieName, value, cookieOptions) {
35
+ if (typeof document === "undefined") {
36
+ return;
37
+ }
38
+ let cookieString = `${cookieName}=${encodeURIComponent(value)}`;
39
+ if (cookieOptions?.maxAge) {
40
+ cookieString += `; max-age=${cookieOptions.maxAge}`;
41
+ } else if (cookieOptions?.expires) {
42
+ cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;
43
+ }
44
+ cookieString += `; path=${path}`;
45
+ if (domain) {
46
+ cookieString += `; domain=${domain}`;
47
+ }
48
+ if (secure) {
49
+ cookieString += "; secure";
50
+ }
51
+ cookieString += `; samesite=${sameSite}`;
52
+ document.cookie = cookieString;
53
+ }
54
+ function removeCookie(cookieName) {
55
+ if (typeof document === "undefined") {
56
+ return;
57
+ }
58
+ let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;
59
+ if (domain) {
60
+ cookieString += `; domain=${domain}`;
61
+ }
62
+ document.cookie = cookieString;
63
+ }
64
+ return {
65
+ getItem: (key) => {
66
+ try {
67
+ const value = getCookie(key);
68
+ return value;
69
+ } catch (error) {
70
+ console.warn("Failed to get cookie:", error);
71
+ return null;
72
+ }
73
+ },
74
+ setItem: (key, value) => {
75
+ try {
76
+ let maxAge = options.maxAge;
77
+ try {
78
+ const parsed = JSON.parse(value);
79
+ if (parsed?.session?.expires_at) {
80
+ const expiresAt = parsed.session.expires_at;
81
+ const now = Math.floor(Date.now() / 1e3);
82
+ const remainingSeconds = expiresAt - now;
83
+ if (remainingSeconds > 0) {
84
+ maxAge = remainingSeconds;
85
+ }
86
+ }
87
+ } catch {
88
+ }
89
+ setCookie(key, value, maxAge ? { maxAge } : void 0);
90
+ } catch (error) {
91
+ console.warn("Failed to set cookie:", error);
92
+ }
93
+ },
94
+ removeItem: (key) => {
95
+ try {
96
+ removeCookie(key);
97
+ } catch (error) {
98
+ console.warn("Failed to remove cookie:", error);
99
+ }
100
+ }
101
+ };
102
+ }
103
+
104
+ // src/auth/store.ts
105
+ var createAuthStore = (cookieOptions) => {
7
106
  return create()(
8
107
  persist(
9
108
  (set) => ({
@@ -27,18 +126,16 @@ var createAuthStore = (storageKey = "anythink_auth_session") => {
27
126
  }
28
127
  }),
29
128
  {
30
- name: storageKey,
129
+ name: cookieOptions?.name ?? "anythink_auth_session",
31
130
  storage: createJSONStorage(() => {
32
- if (typeof globalThis !== "undefined" && "localStorage" in globalThis) {
33
- return globalThis.localStorage;
34
- }
35
- return {
36
- getItem: () => null,
37
- setItem: () => {
38
- },
39
- removeItem: () => {
40
- }
41
- };
131
+ return createCookieStorage({
132
+ name: cookieOptions?.name ?? "anythink_auth_session",
133
+ path: "/",
134
+ secure: typeof window !== "undefined" && window.location.protocol === "https:",
135
+ sameSite: "lax",
136
+ ...cookieOptions
137
+ // User-provided options override defaults
138
+ });
42
139
  }),
43
140
  // Only persist the session, not loading/error states
44
141
  partialize: (state) => ({ session: state.session })
@@ -50,45 +147,20 @@ var createAuthStore = (storageKey = "anythink_auth_session") => {
50
147
  // src/auth/client.ts
51
148
  var AuthClient = class {
52
149
  constructor(config) {
53
- this.config = {
54
- tokenEndpoint: "/auth/v1/token",
55
- refreshEndpoint: "/auth/v1/refresh",
56
- changePasswordEndpoint: "/users/me/password",
57
- storageKey: "anythink_auth_session",
58
- onSignOut: () => {
59
- return;
60
- },
61
- ...config
62
- };
63
- this.store = createAuthStore(this.config.storageKey);
150
+ this.config = config;
151
+ this.store = createAuthStore({
152
+ name: this.config.cookieStorage?.name ?? "anythink_auth_session",
153
+ domain: this.config.cookieStorage?.domain,
154
+ path: this.config.cookieStorage?.path,
155
+ secure: this.config.cookieStorage?.secure,
156
+ sameSite: this.config.cookieStorage?.sameSite
157
+ });
64
158
  this.axiosClient = axios.create({
65
159
  baseURL: this.config.instanceUrl,
66
160
  headers: {
67
161
  "Content-Type": "application/json"
68
162
  }
69
163
  });
70
- if (typeof config.onSessionChanged === "function") {
71
- this.onSessionChanged = config.onSessionChanged;
72
- }
73
- }
74
- /**
75
- * Set the onSessionChanged handler.
76
- * @param handler Callback fired whenever the session changes
77
- */
78
- setOnSessionChanged(handler) {
79
- this.onSessionChanged = handler;
80
- }
81
- /**
82
- * Internal helper to call the session-changed handler, if present.
83
- */
84
- _callSessionChanged(session) {
85
- if (typeof this.onSessionChanged === "function") {
86
- try {
87
- this.onSessionChanged(session);
88
- } catch (e) {
89
- console.warn("onSessionChanged threw:", e);
90
- }
91
- }
92
164
  }
93
165
  /**
94
166
  * Sign in with email and password
@@ -103,7 +175,7 @@ var AuthClient = class {
103
175
  this.store.getState().clearError();
104
176
  const params = orgId ? { org_id: orgId.toString() } : void 0;
105
177
  const response = await this.axiosClient.post(
106
- this.config.tokenEndpoint,
178
+ "/auth/v1/token",
107
179
  { email, password },
108
180
  { params }
109
181
  );
@@ -115,7 +187,6 @@ var AuthClient = class {
115
187
  expires_at: Math.floor(Date.now() / 1e3) + tokenPair.expires_in
116
188
  };
117
189
  this.store.getState().setSession(session);
118
- this._callSessionChanged(session);
119
190
  this.store.getState().setLoading(false);
120
191
  return { data: { session }, error: null };
121
192
  } catch (error) {
@@ -129,7 +200,6 @@ var AuthClient = class {
129
200
  this.store.getState().setError(authError);
130
201
  this.store.getState().setLoading(false);
131
202
  this.store.getState().setSession(null);
132
- this._callSessionChanged(null);
133
203
  return {
134
204
  data: { session: null },
135
205
  error: authError
@@ -185,7 +255,7 @@ var AuthClient = class {
185
255
  this.store.getState().setLoading(true);
186
256
  this.store.getState().clearError();
187
257
  const response = await this.axiosClient.post(
188
- this.config.refreshEndpoint,
258
+ "/auth/v1/refresh",
189
259
  { token: session.refresh_token }
190
260
  );
191
261
  const tokenPair = response.data;
@@ -196,12 +266,10 @@ var AuthClient = class {
196
266
  expires_at: Math.floor(Date.now() / 1e3) + tokenPair.expires_in
197
267
  };
198
268
  this.store.getState().setSession(newSession);
199
- this._callSessionChanged(newSession);
200
269
  this.store.getState().setLoading(false);
201
270
  return { data: { session: newSession }, error: null };
202
271
  } catch (error) {
203
272
  this.store.getState().setSession(null);
204
- this._callSessionChanged(null);
205
273
  this.store.getState().setLoading(false);
206
274
  let authError;
207
275
  if (error instanceof AxiosError) {
@@ -247,10 +315,8 @@ var AuthClient = class {
247
315
  expires_at: Math.floor(Date.now() / 1e3) + expires_in
248
316
  };
249
317
  this.store.getState().setSession(session);
250
- this._callSessionChanged(session);
251
318
  return { error: null };
252
319
  } catch (error) {
253
- this._callSessionChanged(null);
254
320
  return {
255
321
  error: error instanceof Error ? error : new Error("Failed to set session")
256
322
  };
@@ -269,7 +335,7 @@ var AuthClient = class {
269
335
  throw new Error("No access token found");
270
336
  }
271
337
  await this.axiosClient.post(
272
- this.config.changePasswordEndpoint,
338
+ "/users/me/password",
273
339
  {
274
340
  current_password: currentPassword,
275
341
  new_password: newPassword
@@ -296,12 +362,28 @@ var AuthClient = class {
296
362
  }
297
363
  /**
298
364
  * Sign out and clear session
365
+ * Invalidates the refresh token on the server and clears local session
366
+ * @returns Error object or null if successful
299
367
  */
300
368
  async signOut() {
369
+ const refreshToken = this.getRefreshToken();
301
370
  this.store.getState().signOut();
302
- this._callSessionChanged(null);
303
- if (this.config.onSignOut) {
304
- this.config.onSignOut();
371
+ if (refreshToken) {
372
+ try {
373
+ await this.axiosClient.post("/auth/v1/logout", {
374
+ token: refreshToken
375
+ });
376
+ } catch (error) {
377
+ if (error instanceof AxiosError) {
378
+ if (error.response?.status !== 401 && error.response?.status !== 404) {
379
+ console.warn(
380
+ "Failed to invalidate refresh token on server:",
381
+ error.message
382
+ );
383
+ }
384
+ }
385
+ return { error: null };
386
+ }
305
387
  }
306
388
  return { error: null };
307
389
  }
@@ -464,9 +546,6 @@ var AuthenticatedBaseService = class {
464
546
  }
465
547
  };
466
548
 
467
- // src/index.ts
468
- var version = "0.1.1";
469
-
470
- export { AuthClient, AuthenticatedBaseService, createAuthStore, version };
549
+ export { AuthClient, AuthenticatedBaseService, createAuthStore };
471
550
  //# sourceMappingURL=index.mjs.map
472
551
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth/store.ts","../src/auth/client.ts","../src/services/AuthenticatedBaseService.ts","../src/index.ts"],"names":["axios"],"mappings":"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","file":"index.mjs","sourcesContent":["import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session } from \"@/types/auth\";\n\ninterface AuthState {\n session: Session | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with persistence\n * @param storageKey - Key for localStorage persistence\n */\nexport const createAuthStore = (\n storageKey: string = \"anythink_auth_session\"\n) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n signOut: () => {\n set({ session: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: storageKey,\n storage: createJSONStorage(() => {\n // Use localStorage for persistence\n if (\n typeof globalThis !== \"undefined\" &&\n \"localStorage\" in globalThis\n ) {\n return (globalThis as any).localStorage;\n }\n // Fallback for SSR\n return {\n getItem: () => null,\n setItem: () => {},\n removeItem: () => {},\n };\n }),\n // Only persist the session, not loading/error states\n partialize: (state: AuthState) => ({ session: state.session }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: Required<AuthConfig>;\n private onSessionChanged?: (session: Session | null) => void;\n private axiosClient: AxiosInstance;\n\n constructor(\n config: AuthConfig & {\n onSessionChanged?: (session: Session | null) => void;\n }\n ) {\n this.config = {\n tokenEndpoint: \"/auth/v1/token\",\n refreshEndpoint: \"/auth/v1/refresh\",\n changePasswordEndpoint: \"/users/me/password\",\n storageKey: \"anythink_auth_session\",\n onSignOut: () => {\n return;\n },\n ...config,\n };\n\n this.store = createAuthStore(this.config.storageKey);\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (typeof config.onSessionChanged === \"function\") {\n this.onSessionChanged = config.onSessionChanged;\n }\n }\n\n /**\n * Set the onSessionChanged handler.\n * @param handler Callback fired whenever the session changes\n */\n setOnSessionChanged(\n handler: ((session: Session | null) => void) | undefined\n ) {\n this.onSessionChanged = handler;\n }\n\n /**\n * Internal helper to call the session-changed handler, if present.\n */\n private _callSessionChanged(session: Session | null) {\n if (typeof this.onSessionChanged === \"function\") {\n try {\n this.onSessionChanged(session);\n } catch (e) {\n // Avoid throwing in userland\n console.warn(\"onSessionChanged threw:\", e);\n }\n }\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n this.config.tokenEndpoint,\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this._callSessionChanged(session); // Call hook here\n this.store.getState().setLoading(false);\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n this._callSessionChanged(null); // Call hook for failed sign in\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\"/auth/v1/register\", {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n });\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n this.config.refreshEndpoint,\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this._callSessionChanged(newSession); // Call here\n this.store.getState().setLoading(false);\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this._callSessionChanged(null); // Call hook here on null-out\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n\n // Check if session is expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (\n session &&\n session.expires_at &&\n Date.now() >= session.expires_at * 1000\n ) {\n // Session expired, return null\n // The caller should handle refresh if needed\n return { data: { session: null } };\n }\n\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n this._callSessionChanged(session); // Call here\n return { error: null };\n } catch (error) {\n this._callSessionChanged(null); // Defensive, though only on explicit error\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n this.config.changePasswordEndpoint,\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n */\n async signOut(): Promise<{ error: null }> {\n this.store.getState().signOut();\n this._callSessionChanged(null); // Call on sign out\n if (this.config.onSignOut) {\n this.config.onSignOut();\n }\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return null;\n }\n\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n\n // Response interceptor: Handle token refresh on 401\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as AxiosRequestConfig & {\n _retry?: boolean;\n };\n\n // If the error is 401 (Unauthorized) and we haven't already tried to refresh\n if (\n error.response?.status === 401 &&\n originalRequest &&\n !originalRequest._retry\n ) {\n originalRequest._retry = true;\n\n try {\n // Try to refresh the token\n const { data, error: refreshError } =\n await this.authClient.refreshSession();\n\n if (data.session && !refreshError) {\n // Retry the original request with the new token\n const token = this.authClient.getAccessToken();\n if (token) {\n if (!originalRequest.headers) {\n originalRequest.headers = {};\n }\n originalRequest.headers.Authorization = `Bearer ${token}`;\n }\n return this.client(originalRequest);\n } else {\n // Refresh failed, sign out\n await this.authClient.signOut();\n }\n } catch (refreshError) {\n // Refresh failed, sign out\n await this.authClient.signOut();\n return Promise.reject(refreshError);\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n","/**\n * Anythink SDK\n *\n * A reusable Typescript SDK for the Anythink platform.\n */\n\n// Version\nexport const version = \"0.1.1\";\n\n// Auth exports\nexport { AuthClient } from \"@/auth/client\";\nexport { createAuthStore } from \"@/auth/store\";\n\n// Service exports\nexport { AuthenticatedBaseService } from \"@/services/AuthenticatedBaseService\";\n\n// Type exports\nexport type {\n AuthConfig,\n User,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n} from \"@/types/auth\";\n"]}
1
+ {"version":3,"sources":["../src/auth/cookieStorage.ts","../src/auth/store.ts","../src/auth/client.ts","../src/services/AuthenticatedBaseService.ts"],"names":["axios"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Cookie storage adapter that implements the same interface as localStorage\n * for use with Zustand's persist middleware.\n */\nexport interface CookieStorageOptions {\n /**\n * Cookie name/key\n */\n name: string;\n /**\n * Cookie domain (optional)\n */\n domain?: string;\n /**\n * Cookie path (default: '/')\n */\n path?: string;\n /**\n * Whether to use Secure flag (HTTPS only, default: true in production)\n */\n secure?: boolean;\n /**\n * SameSite attribute (default: 'lax')\n */\n sameSite?: \"strict\" | \"lax\" | \"none\";\n /**\n * Maximum age in seconds (optional, for expiration)\n */\n maxAge?: number;\n}\n\n/**\n * Creates a cookie storage adapter compatible with Zustand's persist middleware\n */\nexport function createCookieStorage(options: CookieStorageOptions) {\n const {\n domain,\n path = \"/\",\n secure = typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite = \"lax\",\n } = options;\n\n /**\n * Get a cookie value by name\n */\n function getCookie(cookieName: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const nameEQ = cookieName + \"=\";\n const cookies = document.cookie.split(\";\");\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === \" \") {\n cookie = cookie.substring(1, cookie.length);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(\n cookie.substring(nameEQ.length, cookie.length)\n );\n }\n }\n return null;\n }\n\n /**\n * Set a cookie value\n */\n function setCookie(\n cookieName: string,\n value: string,\n cookieOptions?: {\n maxAge?: number;\n expires?: Date;\n }\n ): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=${encodeURIComponent(value)}`;\n\n if (cookieOptions?.maxAge) {\n cookieString += `; max-age=${cookieOptions.maxAge}`;\n } else if (cookieOptions?.expires) {\n cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n if (secure) {\n cookieString += \"; secure\";\n }\n\n cookieString += `; samesite=${sameSite}`;\n\n document.cookie = cookieString;\n }\n\n /**\n * Remove a cookie\n */\n function removeCookie(cookieName: string): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n }\n\n return {\n getItem: (key: string): string | null => {\n try {\n const value = getCookie(key);\n return value;\n } catch (error) {\n console.warn(\"Failed to get cookie:\", error);\n return null;\n }\n },\n\n setItem: (key: string, value: string): void => {\n try {\n // Try to parse the value as JSON to extract session expiration\n let maxAge: number | undefined = options.maxAge;\n\n try {\n const parsed = JSON.parse(value);\n // If the stored value contains a session with expires_at, calculate maxAge\n if (parsed?.session?.expires_at) {\n const expiresAt = parsed.session.expires_at;\n const now = Math.floor(Date.now() / 1000);\n const remainingSeconds = expiresAt - now;\n // Only set maxAge if it's positive (not expired)\n if (remainingSeconds > 0) {\n maxAge = remainingSeconds;\n }\n }\n } catch {\n // If parsing fails, value is not JSON, use default maxAge if provided\n }\n\n setCookie(key, value, maxAge ? { maxAge } : undefined);\n } catch (error) {\n console.warn(\"Failed to set cookie:\", error);\n }\n },\n\n removeItem: (key: string): void => {\n try {\n removeCookie(key);\n } catch (error) {\n console.warn(\"Failed to remove cookie:\", error);\n }\n },\n };\n}\n","import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session } from \"@/types/auth\";\nimport {\n createCookieStorage,\n type CookieStorageOptions,\n} from \"@/auth/cookieStorage\";\n\ninterface AuthState {\n session: Session | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with cookie-based persistence\n * Always uses cookies with default values, never localStorage\n * @param storageKey - Key for cookie storage (cookie name)\n * @param cookieOptions - Optional cookie configuration options to override defaults\n */\nexport const createAuthStore = (cookieOptions?: CookieStorageOptions) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n signOut: () => {\n set({ session: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n storage: createJSONStorage(() => {\n // Always use cookie storage with defaults\n // Defaults: path='/', secure=true (if HTTPS), sameSite='lax'\n return createCookieStorage({\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n path: \"/\",\n secure:\n typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite: \"lax\",\n ...cookieOptions, // User-provided options override defaults\n });\n }),\n // Only persist the session, not loading/error states\n partialize: (state: AuthState) => ({ session: state.session }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: AuthConfig;\n private axiosClient: AxiosInstance;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.store = createAuthStore({\n name: this.config.cookieStorage?.name ?? \"anythink_auth_session\",\n domain: this.config.cookieStorage?.domain,\n path: this.config.cookieStorage?.path,\n secure: this.config.cookieStorage?.secure,\n sameSite: this.config.cookieStorage?.sameSite,\n });\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n \"/auth/v1/token\",\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this.store.getState().setLoading(false);\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\"/auth/v1/register\", {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n });\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n \"/auth/v1/refresh\",\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this.store.getState().setLoading(false);\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n\n // Check if session is expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (\n session &&\n session.expires_at &&\n Date.now() >= session.expires_at * 1000\n ) {\n // Session expired, return null\n // The caller should handle refresh if needed\n return { data: { session: null } };\n }\n\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n return { error: null };\n } catch (error) {\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n \"/users/me/password\",\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n * Invalidates the refresh token on the server and clears local session\n * @returns Error object or null if successful\n */\n async signOut(): Promise<{ error: Error | null }> {\n const refreshToken = this.getRefreshToken();\n\n // Always clear local session first\n this.store.getState().signOut();\n\n // If we have a refresh token, try to invalidate it on the server\n // This is best practice for security - prevents token reuse\n if (refreshToken) {\n try {\n await this.axiosClient.post(\"/auth/v1/logout\", {\n token: refreshToken,\n });\n } catch (error) {\n // If the API call fails, we've already cleared local session\n // Log the error but don't fail the sign out operation\n // The token may already be invalid or expired, which is fine\n if (error instanceof AxiosError) {\n // Only log if it's not a 401/404 (token already invalid/not found)\n if (\n error.response?.status !== 401 &&\n error.response?.status !== 404\n ) {\n console.warn(\n \"Failed to invalidate refresh token on server:\",\n error.message\n );\n }\n }\n // Return null error - sign out succeeded locally even if server call failed\n return { error: null };\n }\n }\n\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return null;\n }\n\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n\n // Response interceptor: Handle token refresh on 401\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as AxiosRequestConfig & {\n _retry?: boolean;\n };\n\n // If the error is 401 (Unauthorized) and we haven't already tried to refresh\n if (\n error.response?.status === 401 &&\n originalRequest &&\n !originalRequest._retry\n ) {\n originalRequest._retry = true;\n\n try {\n // Try to refresh the token\n const { data, error: refreshError } =\n await this.authClient.refreshSession();\n\n if (data.session && !refreshError) {\n // Retry the original request with the new token\n const token = this.authClient.getAccessToken();\n if (token) {\n if (!originalRequest.headers) {\n originalRequest.headers = {};\n }\n originalRequest.headers.Authorization = `Bearer ${token}`;\n }\n return this.client(originalRequest);\n } else {\n // Refresh failed, sign out\n await this.authClient.signOut();\n }\n } catch (refreshError) {\n // Refresh failed, sign out\n await this.authClient.signOut();\n return Promise.reject(refreshError);\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anythink-cloud/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Reusable Typescript SDK for Anythink platform",
5
5
  "homepage": "https://anythink.cloud",
6
6
  "bugs": "https://github.com/Anythink-Ltd/anythink-sdk/issues",