@anythink-cloud/sdk 0.1.0 → 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 +78 -30
- package/dist/index.d.ts +78 -30
- package/dist/index.js +139 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +140 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -10,6 +10,17 @@ interface TokenPair {
|
|
|
10
10
|
refresh_token: string;
|
|
11
11
|
expires_in: number;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* User structure
|
|
15
|
+
*/
|
|
16
|
+
interface User {
|
|
17
|
+
id: number;
|
|
18
|
+
gid: string;
|
|
19
|
+
first_name: string;
|
|
20
|
+
last_name: string;
|
|
21
|
+
email: string;
|
|
22
|
+
created_at: string;
|
|
23
|
+
}
|
|
13
24
|
/**
|
|
14
25
|
* Session structure for internal use
|
|
15
26
|
*/
|
|
@@ -19,17 +30,38 @@ interface Session {
|
|
|
19
30
|
expires_in: number;
|
|
20
31
|
expires_at: number;
|
|
21
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
|
+
}
|
|
22
58
|
/**
|
|
23
59
|
* Configuration for the auth client
|
|
24
60
|
*/
|
|
25
61
|
interface AuthConfig {
|
|
26
62
|
instanceUrl: string;
|
|
27
63
|
orgId: number;
|
|
28
|
-
|
|
29
|
-
refreshEndpoint?: string;
|
|
30
|
-
changePasswordEndpoint?: string;
|
|
31
|
-
storageKey?: string;
|
|
32
|
-
onSignOut?: () => void;
|
|
64
|
+
cookieStorage?: CookieStorageConfig;
|
|
33
65
|
}
|
|
34
66
|
/**
|
|
35
67
|
* Sign in response
|
|
@@ -50,6 +82,37 @@ interface RefreshResponse {
|
|
|
50
82
|
error: Error | null;
|
|
51
83
|
}
|
|
52
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
|
+
|
|
53
116
|
interface AuthState {
|
|
54
117
|
session: Session | null;
|
|
55
118
|
isLoading: boolean;
|
|
@@ -61,10 +124,12 @@ interface AuthState {
|
|
|
61
124
|
setError: (error: Error | null) => void;
|
|
62
125
|
}
|
|
63
126
|
/**
|
|
64
|
-
* Creates the auth store with persistence
|
|
65
|
-
*
|
|
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
|
|
66
131
|
*/
|
|
67
|
-
declare const createAuthStore: (
|
|
132
|
+
declare const createAuthStore: (cookieOptions?: CookieStorageOptions) => zustand.UseBoundStore<Omit<zustand.StoreApi<AuthState>, "setState" | "persist"> & {
|
|
68
133
|
setState(partial: AuthState | Partial<AuthState> | ((state: AuthState) => AuthState | Partial<AuthState>), replace?: false | undefined): unknown;
|
|
69
134
|
setState(state: AuthState | ((state: AuthState) => AuthState), replace: true): unknown;
|
|
70
135
|
persist: {
|
|
@@ -84,20 +149,8 @@ declare const createAuthStore: (storageKey?: string) => zustand.UseBoundStore<Om
|
|
|
84
149
|
declare class AuthClient {
|
|
85
150
|
private store;
|
|
86
151
|
private config;
|
|
87
|
-
private onSessionChanged?;
|
|
88
152
|
private axiosClient;
|
|
89
|
-
constructor(config: AuthConfig
|
|
90
|
-
onSessionChanged?: (session: Session | null) => void;
|
|
91
|
-
});
|
|
92
|
-
/**
|
|
93
|
-
* Set the onSessionChanged handler.
|
|
94
|
-
* @param handler Callback fired whenever the session changes
|
|
95
|
-
*/
|
|
96
|
-
setOnSessionChanged(handler: ((session: Session | null) => void) | undefined): void;
|
|
97
|
-
/**
|
|
98
|
-
* Internal helper to call the session-changed handler, if present.
|
|
99
|
-
*/
|
|
100
|
-
private _callSessionChanged;
|
|
153
|
+
constructor(config: AuthConfig);
|
|
101
154
|
/**
|
|
102
155
|
* Sign in with email and password
|
|
103
156
|
* @param email User email
|
|
@@ -155,9 +208,11 @@ declare class AuthClient {
|
|
|
155
208
|
}>;
|
|
156
209
|
/**
|
|
157
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
|
|
158
213
|
*/
|
|
159
214
|
signOut(): Promise<{
|
|
160
|
-
error: null;
|
|
215
|
+
error: Error | null;
|
|
161
216
|
}>;
|
|
162
217
|
/**
|
|
163
218
|
* Get the current access token
|
|
@@ -219,11 +274,4 @@ declare class AuthenticatedBaseService {
|
|
|
219
274
|
getClient(): AxiosInstance;
|
|
220
275
|
}
|
|
221
276
|
|
|
222
|
-
|
|
223
|
-
* Anythink SDK
|
|
224
|
-
*
|
|
225
|
-
* A reusable Typescript SDK for the Anythink platform.
|
|
226
|
-
*/
|
|
227
|
-
declare const version = "0.1.0";
|
|
228
|
-
|
|
229
|
-
export { AuthClient, type AuthConfig, AuthenticatedBaseService, type RefreshResponse, type Session, type SignInResponse, type TokenPair, 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
|
@@ -10,6 +10,17 @@ interface TokenPair {
|
|
|
10
10
|
refresh_token: string;
|
|
11
11
|
expires_in: number;
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* User structure
|
|
15
|
+
*/
|
|
16
|
+
interface User {
|
|
17
|
+
id: number;
|
|
18
|
+
gid: string;
|
|
19
|
+
first_name: string;
|
|
20
|
+
last_name: string;
|
|
21
|
+
email: string;
|
|
22
|
+
created_at: string;
|
|
23
|
+
}
|
|
13
24
|
/**
|
|
14
25
|
* Session structure for internal use
|
|
15
26
|
*/
|
|
@@ -19,17 +30,38 @@ interface Session {
|
|
|
19
30
|
expires_in: number;
|
|
20
31
|
expires_at: number;
|
|
21
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
|
+
}
|
|
22
58
|
/**
|
|
23
59
|
* Configuration for the auth client
|
|
24
60
|
*/
|
|
25
61
|
interface AuthConfig {
|
|
26
62
|
instanceUrl: string;
|
|
27
63
|
orgId: number;
|
|
28
|
-
|
|
29
|
-
refreshEndpoint?: string;
|
|
30
|
-
changePasswordEndpoint?: string;
|
|
31
|
-
storageKey?: string;
|
|
32
|
-
onSignOut?: () => void;
|
|
64
|
+
cookieStorage?: CookieStorageConfig;
|
|
33
65
|
}
|
|
34
66
|
/**
|
|
35
67
|
* Sign in response
|
|
@@ -50,6 +82,37 @@ interface RefreshResponse {
|
|
|
50
82
|
error: Error | null;
|
|
51
83
|
}
|
|
52
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
|
+
|
|
53
116
|
interface AuthState {
|
|
54
117
|
session: Session | null;
|
|
55
118
|
isLoading: boolean;
|
|
@@ -61,10 +124,12 @@ interface AuthState {
|
|
|
61
124
|
setError: (error: Error | null) => void;
|
|
62
125
|
}
|
|
63
126
|
/**
|
|
64
|
-
* Creates the auth store with persistence
|
|
65
|
-
*
|
|
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
|
|
66
131
|
*/
|
|
67
|
-
declare const createAuthStore: (
|
|
132
|
+
declare const createAuthStore: (cookieOptions?: CookieStorageOptions) => zustand.UseBoundStore<Omit<zustand.StoreApi<AuthState>, "setState" | "persist"> & {
|
|
68
133
|
setState(partial: AuthState | Partial<AuthState> | ((state: AuthState) => AuthState | Partial<AuthState>), replace?: false | undefined): unknown;
|
|
69
134
|
setState(state: AuthState | ((state: AuthState) => AuthState), replace: true): unknown;
|
|
70
135
|
persist: {
|
|
@@ -84,20 +149,8 @@ declare const createAuthStore: (storageKey?: string) => zustand.UseBoundStore<Om
|
|
|
84
149
|
declare class AuthClient {
|
|
85
150
|
private store;
|
|
86
151
|
private config;
|
|
87
|
-
private onSessionChanged?;
|
|
88
152
|
private axiosClient;
|
|
89
|
-
constructor(config: AuthConfig
|
|
90
|
-
onSessionChanged?: (session: Session | null) => void;
|
|
91
|
-
});
|
|
92
|
-
/**
|
|
93
|
-
* Set the onSessionChanged handler.
|
|
94
|
-
* @param handler Callback fired whenever the session changes
|
|
95
|
-
*/
|
|
96
|
-
setOnSessionChanged(handler: ((session: Session | null) => void) | undefined): void;
|
|
97
|
-
/**
|
|
98
|
-
* Internal helper to call the session-changed handler, if present.
|
|
99
|
-
*/
|
|
100
|
-
private _callSessionChanged;
|
|
153
|
+
constructor(config: AuthConfig);
|
|
101
154
|
/**
|
|
102
155
|
* Sign in with email and password
|
|
103
156
|
* @param email User email
|
|
@@ -155,9 +208,11 @@ declare class AuthClient {
|
|
|
155
208
|
}>;
|
|
156
209
|
/**
|
|
157
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
|
|
158
213
|
*/
|
|
159
214
|
signOut(): Promise<{
|
|
160
|
-
error: null;
|
|
215
|
+
error: Error | null;
|
|
161
216
|
}>;
|
|
162
217
|
/**
|
|
163
218
|
* Get the current access token
|
|
@@ -219,11 +274,4 @@ declare class AuthenticatedBaseService {
|
|
|
219
274
|
getClient(): AxiosInstance;
|
|
220
275
|
}
|
|
221
276
|
|
|
222
|
-
|
|
223
|
-
* Anythink SDK
|
|
224
|
-
*
|
|
225
|
-
* A reusable Typescript SDK for the Anythink platform.
|
|
226
|
-
*/
|
|
227
|
-
declare const version = "0.1.0";
|
|
228
|
-
|
|
229
|
-
export { AuthClient, type AuthConfig, AuthenticatedBaseService, type RefreshResponse, type Session, type SignInResponse, type TokenPair, 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
|
-
|
|
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:
|
|
135
|
+
name: cookieOptions?.name ?? "anythink_auth_session",
|
|
37
136
|
storage: middleware.createJSONStorage(() => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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.0";
|
|
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.0\";\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 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
|
-
|
|
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:
|
|
129
|
+
name: cookieOptions?.name ?? "anythink_auth_session",
|
|
31
130
|
storage: createJSONStorage(() => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
468
|
-
var version = "0.1.0";
|
|
469
|
-
|
|
470
|
-
export { AuthClient, AuthenticatedBaseService, createAuthStore, version };
|
|
549
|
+
export { AuthClient, AuthenticatedBaseService, createAuthStore };
|
|
471
550
|
//# sourceMappingURL=index.mjs.map
|
|
472
551
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -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.0\";\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 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