@take-out/better-auth-utils 0.0.67 → 0.0.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -104
- package/dist/cjs/createAuthClient.cjs +38 -27
- package/dist/cjs/createAuthClient.js +32 -37
- package/dist/cjs/createAuthClient.js.map +2 -2
- package/dist/cjs/createAuthClient.native.js +57 -33
- package/dist/cjs/createAuthClient.native.js.map +1 -1
- package/dist/cjs/server.cjs +94 -0
- package/dist/cjs/server.js +87 -0
- package/dist/cjs/server.js.map +6 -0
- package/dist/cjs/server.native.js +196 -0
- package/dist/cjs/server.native.js.map +1 -0
- package/dist/esm/createAuthClient.js +32 -37
- package/dist/esm/createAuthClient.js.map +2 -2
- package/dist/esm/createAuthClient.mjs +38 -27
- package/dist/esm/createAuthClient.mjs.map +1 -1
- package/dist/esm/createAuthClient.native.js +57 -33
- package/dist/esm/createAuthClient.native.js.map +1 -1
- package/dist/esm/server.js +71 -0
- package/dist/esm/server.js.map +6 -0
- package/dist/esm/server.mjs +67 -0
- package/dist/esm/server.mjs.map +1 -0
- package/dist/esm/server.native.js +166 -0
- package/dist/esm/server.native.js.map +1 -0
- package/package.json +11 -4
- package/src/createAuthClient.ts +74 -70
- package/src/server.ts +149 -0
- package/types/createAuthClient.d.ts +13 -6
- package/types/createAuthClient.d.ts.map +2 -2
- package/types/server.d.ts +45 -0
- package/types/server.d.ts.map +19 -0
package/README.md
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
# @take-out/better-auth-utils
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- JWT support for Zero, web and React Native
|
|
8
|
-
- Session persistence in local storage
|
|
9
|
-
- Token validation and refresh
|
|
10
|
-
- State management with emitters
|
|
11
|
-
- Automatic retry on authentication errors
|
|
12
|
-
- TypeScript support with full type safety
|
|
3
|
+
Auth utilities for better-auth with React/React Native support.
|
|
13
4
|
|
|
14
5
|
## Installation
|
|
15
6
|
|
|
@@ -17,120 +8,99 @@ Better Auth utilities and helpers for React/React Native applications.
|
|
|
17
8
|
bun add @take-out/better-auth-utils
|
|
18
9
|
```
|
|
19
10
|
|
|
20
|
-
## Usage
|
|
21
|
-
|
|
22
|
-
### Basic Setup
|
|
11
|
+
## Client Usage
|
|
23
12
|
|
|
24
13
|
```typescript
|
|
25
14
|
import { createBetterAuthClient } from '@take-out/better-auth-utils'
|
|
26
|
-
import { adminClient, magicLinkClient } from 'better-auth/client/plugins'
|
|
27
|
-
|
|
28
|
-
const authClient = createBetterAuthClient({
|
|
29
|
-
baseURL: 'https://your-app.com',
|
|
30
|
-
plugins: [adminClient(), magicLinkClient()],
|
|
31
|
-
// Optional callbacks
|
|
32
|
-
onAuthStateChange: (state) => {
|
|
33
|
-
console.info('Auth state changed:', state)
|
|
34
|
-
},
|
|
35
|
-
onAuthError: (error) => {
|
|
36
|
-
console.error('Auth error:', error)
|
|
37
|
-
},
|
|
38
|
-
})
|
|
39
15
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
### Using in React Components
|
|
16
|
+
const auth = createBetterAuthClient({
|
|
17
|
+
baseURL: 'https://myapp.com',
|
|
18
|
+
plugins: [/* better-auth plugins */],
|
|
19
|
+
// transform user object with app-specific fields
|
|
20
|
+
createUser: (user) => ({ ...user, role: user.role as 'admin' | undefined }),
|
|
21
|
+
// optional callbacks
|
|
22
|
+
onAuthStateChange: (state) => console.log('Auth changed:', state),
|
|
23
|
+
onAuthError: (error) => console.error('Auth error:', error),
|
|
24
|
+
})
|
|
51
25
|
|
|
52
|
-
|
|
53
|
-
|
|
26
|
+
// React hook for auth state
|
|
27
|
+
const { state, user, token } = auth.useAuth()
|
|
54
28
|
|
|
55
|
-
|
|
56
|
-
|
|
29
|
+
// get current auth state (non-reactive)
|
|
30
|
+
const { loggedIn } = auth.getAuth()
|
|
57
31
|
|
|
58
|
-
|
|
59
|
-
|
|
32
|
+
// clear all auth (localStorage + cookies)
|
|
33
|
+
auth.clearAllAuth()
|
|
60
34
|
|
|
61
|
-
|
|
62
|
-
|
|
35
|
+
// clear just localStorage token
|
|
36
|
+
auth.clearAuthClientToken()
|
|
63
37
|
```
|
|
64
38
|
|
|
65
|
-
###
|
|
39
|
+
### Client Options
|
|
40
|
+
|
|
41
|
+
| Option | Type | Default | Description |
|
|
42
|
+
|--------|------|---------|-------------|
|
|
43
|
+
| `baseURL` | `string` | required | Auth server URL |
|
|
44
|
+
| `plugins` | `array` | `[]` | better-auth client plugins |
|
|
45
|
+
| `createUser` | `function` | identity | Transform user object with app-specific typing |
|
|
46
|
+
| `onAuthStateChange` | `function` | - | Callback when auth state changes |
|
|
47
|
+
| `onAuthError` | `function` | - | Callback for auth errors |
|
|
48
|
+
| `storagePrefix` | `string` | `'auth'` | localStorage key prefix |
|
|
49
|
+
| `retryDelay` | `number` | `4000` | Retry delay after errors (ms) |
|
|
50
|
+
| `tokenValidationEndpoint` | `string` | `'/api/auth/validateToken'` | JWT validation endpoint |
|
|
51
|
+
| `authCookieNames` | `string[]` | `['better-auth.jwt', 'better-auth.session_token']` | Cookie names to clear on `clearAllAuth()` |
|
|
52
|
+
|
|
53
|
+
### Client API
|
|
54
|
+
|
|
55
|
+
- `useAuth()` - React hook returning `{ state, user, session, token }`
|
|
56
|
+
- `getAuth()` - Get current auth state (non-reactive), includes `loggedIn` boolean
|
|
57
|
+
- `setAuthClientToken({ token, session })` - Set auth token and session
|
|
58
|
+
- `clearAuthClientToken()` - Clear localStorage token only
|
|
59
|
+
- `clearAllAuth()` - Clear localStorage AND cookies
|
|
60
|
+
- `clearState()` - Clear all auth state and storage
|
|
61
|
+
- `getValidToken()` - Get valid JWT, refreshing if needed
|
|
62
|
+
- `authState` - Emitter for subscribing to auth changes
|
|
63
|
+
- `authClientVersion` - Emitter that updates when auth client recreates
|
|
64
|
+
|
|
65
|
+
## Server Usage
|
|
66
66
|
|
|
67
67
|
```typescript
|
|
68
|
-
import
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
import {
|
|
69
|
+
validateToken,
|
|
70
|
+
isValidJWT,
|
|
71
|
+
InvalidTokenError,
|
|
72
|
+
} from '@take-out/better-auth-utils/server'
|
|
73
|
+
|
|
74
|
+
// validate JWT against JWKS endpoint
|
|
75
|
+
try {
|
|
76
|
+
const payload = await validateToken(token, {
|
|
77
|
+
baseUrl: 'https://myapp.com',
|
|
78
|
+
forceIssuer: process.env.FORCE_ISSUER, // optional, for CI
|
|
79
|
+
jwksPath: '/api/auth/jwks', // optional, default
|
|
80
|
+
})
|
|
81
|
+
console.log('User ID:', payload.sub)
|
|
82
|
+
} catch (err) {
|
|
83
|
+
if (err instanceof InvalidTokenError) {
|
|
84
|
+
// token invalid (malformed, expired, signature mismatch, etc)
|
|
85
|
+
return Response.json({ error: 'INVALID_TOKEN' }, { status: 401 })
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
88
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
})
|
|
89
|
+
// simple boolean check
|
|
90
|
+
const valid = await isValidJWT(token, { baseUrl: 'https://myapp.com' })
|
|
80
91
|
```
|
|
81
92
|
|
|
82
|
-
###
|
|
83
|
-
|
|
84
|
-
- `baseURL` - The base URL for your auth server
|
|
85
|
-
- `plugins` - Array of better-auth plugins
|
|
86
|
-
- `onAuthStateChange` - Callback when auth state changes
|
|
87
|
-
- `onAuthError` - Callback for handling auth errors
|
|
88
|
-
- `storagePrefix` - Prefix for local storage keys (default: 'auth')
|
|
89
|
-
- `retryDelay` - Delay in ms after auth errors (default: 4000)
|
|
90
|
-
- `tokenValidationEndpoint` - Custom token validation endpoint (default:
|
|
91
|
-
'/api/auth/validateToken')
|
|
92
|
-
|
|
93
|
-
## API
|
|
94
|
-
|
|
95
|
-
### `createBetterAuthClient(options)`
|
|
96
|
-
|
|
97
|
-
Creates a new authentication client with the provided options.
|
|
93
|
+
### Server Exports
|
|
98
94
|
|
|
99
|
-
|
|
95
|
+
| Export | Description |
|
|
96
|
+
|--------|-------------|
|
|
97
|
+
| `validateToken(token, options)` | Validate JWT against JWKS, returns payload |
|
|
98
|
+
| `isValidJWT(token, options)` | Boolean validation check |
|
|
99
|
+
| `InvalidTokenError` | Error thrown for invalid tokens |
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
### JWKS Validation
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
Gets the current authentication state (non-reactive).
|
|
106
|
-
|
|
107
|
-
### `setAuthClientToken({ token, session })`
|
|
108
|
-
|
|
109
|
-
Sets the authentication token and session.
|
|
110
|
-
|
|
111
|
-
### `clearAuthClientToken()`
|
|
112
|
-
|
|
113
|
-
Clears the stored authentication token.
|
|
114
|
-
|
|
115
|
-
### `clearState()`
|
|
116
|
-
|
|
117
|
-
Clears all authentication state and storage.
|
|
118
|
-
|
|
119
|
-
## Development
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
# Install dependencies
|
|
123
|
-
bun install
|
|
124
|
-
|
|
125
|
-
# Build the package
|
|
126
|
-
bun run build
|
|
127
|
-
|
|
128
|
-
# Run in watch mode
|
|
129
|
-
bun run watch
|
|
130
|
-
|
|
131
|
-
# Lint the code
|
|
132
|
-
bun run lint:fix
|
|
133
|
-
```
|
|
103
|
+
The server validates JWTs against the JWKS endpoint (`/api/auth/jwks` by default). A fresh JWKS is fetched for each validation to avoid stale key cache issues.
|
|
134
104
|
|
|
135
105
|
## License
|
|
136
106
|
|
|
@@ -32,7 +32,8 @@ function createBetterAuthClient(options) {
|
|
|
32
32
|
createUser,
|
|
33
33
|
storagePrefix = "auth",
|
|
34
34
|
retryDelay = 4e3,
|
|
35
|
-
|
|
35
|
+
useJWT = !1,
|
|
36
|
+
authCookieNames = ["better-auth.jwt", "better-auth.session_token"],
|
|
36
37
|
...authClientOptions
|
|
37
38
|
} = options,
|
|
38
39
|
empty = {
|
|
@@ -41,19 +42,25 @@ function createBetterAuthClient(options) {
|
|
|
41
42
|
user: null,
|
|
42
43
|
token: null
|
|
43
44
|
},
|
|
45
|
+
keysStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-keys`),
|
|
46
|
+
stateStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-state`),
|
|
44
47
|
createAuthClientWithSession = session => (0, import_client.createAuthClient)({
|
|
45
48
|
...authClientOptions,
|
|
46
49
|
fetchOptions: {
|
|
47
|
-
|
|
50
|
+
credentials: "include",
|
|
51
|
+
headers: useJWT ? {
|
|
48
52
|
Authorization: `Bearer ${session}`
|
|
49
|
-
}
|
|
53
|
+
} : void 0
|
|
50
54
|
}
|
|
51
|
-
})
|
|
52
|
-
keysStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-keys`),
|
|
53
|
-
stateStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-state`);
|
|
55
|
+
});
|
|
54
56
|
let authClient = (() => {
|
|
55
57
|
const existingSession = keysStorage.get()?.session;
|
|
56
|
-
return existingSession ? createAuthClientWithSession(existingSession) : (0, import_client.createAuthClient)(
|
|
58
|
+
return existingSession ? createAuthClientWithSession(existingSession) : (0, import_client.createAuthClient)({
|
|
59
|
+
...authClientOptions,
|
|
60
|
+
fetchOptions: {
|
|
61
|
+
credentials: "include"
|
|
62
|
+
}
|
|
63
|
+
});
|
|
57
64
|
})();
|
|
58
65
|
const authState = (0, import_helpers.createEmitter)("authState", stateStorage.get() || empty, {
|
|
59
66
|
comparator: import_helpers.isEqualDeepLite
|
|
@@ -67,6 +74,9 @@ function createBetterAuthClient(options) {
|
|
|
67
74
|
stateStorage.set(next), authState.emit(next), next.token && next.session ? keysStorage.set({
|
|
68
75
|
token: next.token,
|
|
69
76
|
session: next.session.token
|
|
77
|
+
}) : next.session ? keysStorage.set({
|
|
78
|
+
token: "",
|
|
79
|
+
session: next.session.token
|
|
70
80
|
}) : keysStorage.set({
|
|
71
81
|
token: "",
|
|
72
82
|
session: ""
|
|
@@ -97,15 +107,19 @@ function createBetterAuthClient(options) {
|
|
|
97
107
|
sessionUpdate = nextState === "loading" ? {} : {
|
|
98
108
|
session: data?.session ?? null,
|
|
99
109
|
user: data?.user ? createUser ? createUser(data.user) : data.user : null
|
|
100
|
-
}
|
|
110
|
+
},
|
|
111
|
+
previousSession = authState.value?.session,
|
|
112
|
+
isNewSession = data?.session && (!previousSession || previousSession.id !== data.session.id || previousSession.userId !== data.session.userId);
|
|
101
113
|
setState({
|
|
102
114
|
state: nextState,
|
|
103
115
|
...sessionUpdate
|
|
104
|
-
}), data?.session && !authState.value.token &&
|
|
116
|
+
}), useJWT && data?.session && (isNewSession || !authState.value.token) && (isNewSession && authState.value.token && setState({
|
|
117
|
+
token: null
|
|
118
|
+
}), getValidToken().then(token => {
|
|
105
119
|
token && setState({
|
|
106
120
|
token
|
|
107
121
|
});
|
|
108
|
-
});
|
|
122
|
+
}));
|
|
109
123
|
});
|
|
110
124
|
}
|
|
111
125
|
function scheduleAuthRetry(delayMs) {
|
|
@@ -114,20 +128,6 @@ function createBetterAuthClient(options) {
|
|
|
114
128
|
}, delayMs);
|
|
115
129
|
}
|
|
116
130
|
async function getValidToken() {
|
|
117
|
-
const existing = keysStorage.get()?.token;
|
|
118
|
-
if (existing) try {
|
|
119
|
-
if ((await fetch(tokenValidationEndpoint, {
|
|
120
|
-
method: "POST",
|
|
121
|
-
headers: {
|
|
122
|
-
"Content-Type": "application/json"
|
|
123
|
-
},
|
|
124
|
-
body: JSON.stringify({
|
|
125
|
-
token: existing
|
|
126
|
-
})
|
|
127
|
-
}).then(res2 => res2.json()))?.valid) return existing;
|
|
128
|
-
} catch (error) {
|
|
129
|
-
console.error("Error validating token:", error);
|
|
130
|
-
}
|
|
131
131
|
const res = await authClient.$fetch("/token");
|
|
132
132
|
if (res.error) {
|
|
133
133
|
console.error(`Error fetching token: ${res.error.statusText}`);
|
|
@@ -136,9 +136,19 @@ function createBetterAuthClient(options) {
|
|
|
136
136
|
return res.data?.token;
|
|
137
137
|
}
|
|
138
138
|
const clearAuthClientToken = () => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
keysStorage.remove();
|
|
140
|
+
};
|
|
141
|
+
function clearAuthCookies() {
|
|
142
|
+
if (!(typeof document > "u")) for (const cookieName of authCookieNames) {
|
|
143
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
|
|
144
|
+
const domain = window.location.hostname;
|
|
145
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${domain}`, domain.startsWith(".") && (document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${domain.slice(1)}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function clearAllAuth() {
|
|
149
|
+
clearAuthCookies(), clearState();
|
|
150
|
+
}
|
|
151
|
+
const getAuth = () => {
|
|
142
152
|
const state = authState?.value || empty;
|
|
143
153
|
return {
|
|
144
154
|
...state,
|
|
@@ -169,6 +179,7 @@ function createBetterAuthClient(options) {
|
|
|
169
179
|
authClient: proxiedAuthClient,
|
|
170
180
|
setAuthClientToken,
|
|
171
181
|
clearAuthClientToken,
|
|
182
|
+
clearAllAuth,
|
|
172
183
|
useAuth,
|
|
173
184
|
getAuth,
|
|
174
185
|
getValidToken,
|
|
@@ -25,40 +25,41 @@ function createBetterAuthClient(options) {
|
|
|
25
25
|
createUser,
|
|
26
26
|
storagePrefix = "auth",
|
|
27
27
|
retryDelay = 4e3,
|
|
28
|
-
|
|
28
|
+
useJWT = !1,
|
|
29
|
+
authCookieNames = ["better-auth.jwt", "better-auth.session_token"],
|
|
29
30
|
...authClientOptions
|
|
30
31
|
} = options, empty = {
|
|
31
32
|
state: "logged-out",
|
|
32
33
|
session: null,
|
|
33
34
|
user: null,
|
|
34
35
|
token: null
|
|
35
|
-
}, createAuthClientWithSession = (session) => (0, import_client.createAuthClient)({
|
|
36
|
+
}, keysStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-keys`), stateStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-state`), createAuthClientWithSession = (session) => (0, import_client.createAuthClient)({
|
|
36
37
|
...authClientOptions,
|
|
37
38
|
fetchOptions: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
39
|
+
credentials: "include",
|
|
40
|
+
headers: useJWT ? { Authorization: `Bearer ${session}` } : void 0
|
|
41
41
|
}
|
|
42
|
-
})
|
|
42
|
+
});
|
|
43
43
|
let authClient = (() => {
|
|
44
44
|
const existingSession = keysStorage.get()?.session;
|
|
45
|
-
return existingSession ? createAuthClientWithSession(existingSession) : (0, import_client.createAuthClient)(
|
|
45
|
+
return existingSession ? createAuthClientWithSession(existingSession) : (0, import_client.createAuthClient)({
|
|
46
|
+
...authClientOptions,
|
|
47
|
+
fetchOptions: { credentials: "include" }
|
|
48
|
+
});
|
|
46
49
|
})();
|
|
47
50
|
const authState = (0, import_helpers.createEmitter)(
|
|
48
51
|
"authState",
|
|
49
52
|
stateStorage.get() || empty,
|
|
50
|
-
{
|
|
51
|
-
comparator: import_helpers.isEqualDeepLite
|
|
52
|
-
}
|
|
53
|
+
{ comparator: import_helpers.isEqualDeepLite }
|
|
53
54
|
), authClientVersion = (0, import_helpers.createEmitter)("authClientVersion", 0), setState = (update) => {
|
|
54
55
|
const next = { ...authState.value, ...update };
|
|
55
56
|
stateStorage.set(next), authState.emit(next), next.token && next.session ? keysStorage.set({
|
|
56
57
|
token: next.token,
|
|
57
58
|
session: next.session.token
|
|
58
|
-
}) : keysStorage.set({
|
|
59
|
+
}) : next.session ? keysStorage.set({
|
|
59
60
|
token: "",
|
|
60
|
-
session:
|
|
61
|
-
}), onAuthStateChange?.(next);
|
|
61
|
+
session: next.session.token
|
|
62
|
+
}) : keysStorage.set({ token: "", session: "" }), onAuthStateChange?.(next);
|
|
62
63
|
}, setAuthClientToken = async (props) => {
|
|
63
64
|
keysStorage.set(props), updateAuthClient(props.session);
|
|
64
65
|
};
|
|
@@ -76,13 +77,13 @@ function createBetterAuthClient(options) {
|
|
|
76
77
|
const data = dataGeneric, hasPersistedSession = !!keysStorage.get()?.session, nextState = isPending ? "loading" : data?.session ? "logged-in" : hasPersistedSession && data === void 0 ? "loading" : "logged-out", sessionUpdate = nextState === "loading" ? {} : {
|
|
77
78
|
session: data?.session ?? null,
|
|
78
79
|
user: data?.user ? createUser ? createUser(data.user) : data.user : null
|
|
79
|
-
};
|
|
80
|
+
}, previousSession = authState.value?.session, isNewSession = data?.session && (!previousSession || previousSession.id !== data.session.id || previousSession.userId !== data.session.userId);
|
|
80
81
|
setState({
|
|
81
82
|
state: nextState,
|
|
82
83
|
...sessionUpdate
|
|
83
|
-
}), data?.session && !authState.value.token && getValidToken().then((token) => {
|
|
84
|
+
}), useJWT && data?.session && (isNewSession || !authState.value.token) && (isNewSession && authState.value.token && setState({ token: null }), getValidToken().then((token) => {
|
|
84
85
|
token && setState({ token });
|
|
85
|
-
});
|
|
86
|
+
}));
|
|
86
87
|
});
|
|
87
88
|
}
|
|
88
89
|
function scheduleAuthRetry(delayMs) {
|
|
@@ -91,22 +92,6 @@ function createBetterAuthClient(options) {
|
|
|
91
92
|
}, delayMs);
|
|
92
93
|
}
|
|
93
94
|
async function getValidToken() {
|
|
94
|
-
const existing = keysStorage.get()?.token;
|
|
95
|
-
if (existing)
|
|
96
|
-
try {
|
|
97
|
-
if ((await fetch(tokenValidationEndpoint, {
|
|
98
|
-
method: "POST",
|
|
99
|
-
headers: {
|
|
100
|
-
"Content-Type": "application/json"
|
|
101
|
-
},
|
|
102
|
-
body: JSON.stringify({
|
|
103
|
-
token: existing
|
|
104
|
-
})
|
|
105
|
-
}).then((res2) => res2.json()))?.valid)
|
|
106
|
-
return existing;
|
|
107
|
-
} catch (error) {
|
|
108
|
-
console.error("Error validating token:", error);
|
|
109
|
-
}
|
|
110
95
|
const res = await authClient.$fetch("/token");
|
|
111
96
|
if (res.error) {
|
|
112
97
|
console.error(`Error fetching token: ${res.error.statusText}`);
|
|
@@ -116,12 +101,21 @@ function createBetterAuthClient(options) {
|
|
|
116
101
|
}
|
|
117
102
|
const clearAuthClientToken = () => {
|
|
118
103
|
keysStorage.remove();
|
|
119
|
-
}
|
|
104
|
+
};
|
|
105
|
+
function clearAuthCookies() {
|
|
106
|
+
if (!(typeof document > "u"))
|
|
107
|
+
for (const cookieName of authCookieNames) {
|
|
108
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
|
|
109
|
+
const domain = window.location.hostname;
|
|
110
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${domain}`, domain.startsWith(".") && (document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${domain.slice(1)}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function clearAllAuth() {
|
|
114
|
+
clearAuthCookies(), clearState();
|
|
115
|
+
}
|
|
116
|
+
const getAuth = () => {
|
|
120
117
|
const state = authState?.value || empty;
|
|
121
|
-
return {
|
|
122
|
-
...state,
|
|
123
|
-
loggedIn: !!state.session
|
|
124
|
-
};
|
|
118
|
+
return { ...state, loggedIn: !!state.session };
|
|
125
119
|
}, useAuth = () => (0, import_helpers.useEmitterValue)(authState) || empty;
|
|
126
120
|
function clearState() {
|
|
127
121
|
keysStorage.remove(), stateStorage.remove(), setState(empty);
|
|
@@ -146,6 +140,7 @@ function createBetterAuthClient(options) {
|
|
|
146
140
|
authClient: proxiedAuthClient,
|
|
147
141
|
setAuthClientToken,
|
|
148
142
|
clearAuthClientToken,
|
|
143
|
+
clearAllAuth,
|
|
149
144
|
useAuth,
|
|
150
145
|
getAuth,
|
|
151
146
|
getValidToken,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/createAuthClient.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
5
|
-
"names": [
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
6
|
}
|
|
@@ -34,7 +34,8 @@ function createBetterAuthClient(options) {
|
|
|
34
34
|
createUser,
|
|
35
35
|
storagePrefix = "auth",
|
|
36
36
|
retryDelay = 4e3,
|
|
37
|
-
|
|
37
|
+
useJWT = !1,
|
|
38
|
+
authCookieNames = ["better-auth.jwt", "better-auth.session_token"],
|
|
38
39
|
...authClientOptions
|
|
39
40
|
} = options,
|
|
40
41
|
empty = {
|
|
@@ -43,22 +44,28 @@ function createBetterAuthClient(options) {
|
|
|
43
44
|
user: null,
|
|
44
45
|
token: null
|
|
45
46
|
},
|
|
47
|
+
keysStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-keys`),
|
|
48
|
+
stateStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-state`),
|
|
46
49
|
createAuthClientWithSession = function (session) {
|
|
47
50
|
return (0, import_client.createAuthClient)({
|
|
48
51
|
...authClientOptions,
|
|
49
52
|
fetchOptions: {
|
|
50
|
-
|
|
53
|
+
credentials: "include",
|
|
54
|
+
headers: useJWT ? {
|
|
51
55
|
Authorization: `Bearer ${session}`
|
|
52
|
-
}
|
|
56
|
+
} : void 0
|
|
53
57
|
}
|
|
54
58
|
});
|
|
55
59
|
},
|
|
56
|
-
keysStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-keys`),
|
|
57
|
-
stateStorage = (0, import_helpers.createStorageValue)(`${storagePrefix}-state`),
|
|
58
60
|
authClient = function () {
|
|
59
61
|
var _keysStorage_get,
|
|
60
62
|
existingSession = (_keysStorage_get = keysStorage.get()) === null || _keysStorage_get === void 0 ? void 0 : _keysStorage_get.session;
|
|
61
|
-
return existingSession ? createAuthClientWithSession(existingSession) : (0, import_client.createAuthClient)(
|
|
63
|
+
return existingSession ? createAuthClientWithSession(existingSession) : (0, import_client.createAuthClient)({
|
|
64
|
+
...authClientOptions,
|
|
65
|
+
fetchOptions: {
|
|
66
|
+
credentials: "include"
|
|
67
|
+
}
|
|
68
|
+
});
|
|
62
69
|
}(),
|
|
63
70
|
authState = (0, import_helpers.createEmitter)("authState", stateStorage.get() || empty, {
|
|
64
71
|
comparator: import_helpers.isEqualDeepLite
|
|
@@ -73,6 +80,9 @@ function createBetterAuthClient(options) {
|
|
|
73
80
|
stateStorage.set(next), authState.emit(next), next.token && next.session ? keysStorage.set({
|
|
74
81
|
token: next.token,
|
|
75
82
|
session: next.session.token
|
|
83
|
+
}) : next.session ? keysStorage.set({
|
|
84
|
+
token: "",
|
|
85
|
+
session: next.session.token
|
|
76
86
|
}) : keysStorage.set({
|
|
77
87
|
token: "",
|
|
78
88
|
session: ""
|
|
@@ -89,6 +99,7 @@ function createBetterAuthClient(options) {
|
|
|
89
99
|
function subscribeToAuthEffect() {
|
|
90
100
|
dispose?.(), dispose = authClient.useSession.subscribe(async function (props) {
|
|
91
101
|
var _keysStorage_get,
|
|
102
|
+
_authState_value,
|
|
92
103
|
{
|
|
93
104
|
data: dataGeneric,
|
|
94
105
|
isPending,
|
|
@@ -105,15 +116,19 @@ function createBetterAuthClient(options) {
|
|
|
105
116
|
sessionUpdate = nextState === "loading" ? {} : {
|
|
106
117
|
session: (_data_session = data?.session) !== null && _data_session !== void 0 ? _data_session : null,
|
|
107
118
|
user: data?.user ? createUser ? createUser(data.user) : data.user : null
|
|
108
|
-
}
|
|
119
|
+
},
|
|
120
|
+
previousSession = (_authState_value = authState.value) === null || _authState_value === void 0 ? void 0 : _authState_value.session,
|
|
121
|
+
isNewSession = data?.session && (!previousSession || previousSession.id !== data.session.id || previousSession.userId !== data.session.userId);
|
|
109
122
|
setState({
|
|
110
123
|
state: nextState,
|
|
111
124
|
...sessionUpdate
|
|
112
|
-
}), data?.session && !authState.value.token &&
|
|
125
|
+
}), useJWT && data?.session && (isNewSession || !authState.value.token) && (isNewSession && authState.value.token && setState({
|
|
126
|
+
token: null
|
|
127
|
+
}), getValidToken().then(function (token) {
|
|
113
128
|
token && setState({
|
|
114
129
|
token
|
|
115
130
|
});
|
|
116
|
-
});
|
|
131
|
+
}));
|
|
117
132
|
});
|
|
118
133
|
}
|
|
119
134
|
function scheduleAuthRetry(delayMs) {
|
|
@@ -122,36 +137,44 @@ function createBetterAuthClient(options) {
|
|
|
122
137
|
}, delayMs);
|
|
123
138
|
}
|
|
124
139
|
async function getValidToken() {
|
|
125
|
-
var
|
|
126
|
-
|
|
127
|
-
if (existing) try {
|
|
128
|
-
var response = await fetch(tokenValidationEndpoint, {
|
|
129
|
-
method: "POST",
|
|
130
|
-
headers: {
|
|
131
|
-
"Content-Type": "application/json"
|
|
132
|
-
},
|
|
133
|
-
body: JSON.stringify({
|
|
134
|
-
token: existing
|
|
135
|
-
})
|
|
136
|
-
}).then(function (res2) {
|
|
137
|
-
return res2.json();
|
|
138
|
-
});
|
|
139
|
-
if (response?.valid) return existing;
|
|
140
|
-
} catch (error) {
|
|
141
|
-
console.error("Error validating token:", error);
|
|
142
|
-
}
|
|
143
|
-
var res = await authClient.$fetch("/token");
|
|
140
|
+
var _res_data,
|
|
141
|
+
res = await authClient.$fetch("/token");
|
|
144
142
|
if (res.error) {
|
|
145
143
|
console.error(`Error fetching token: ${res.error.statusText}`);
|
|
146
144
|
return;
|
|
147
145
|
}
|
|
148
|
-
|
|
149
|
-
return data?.token;
|
|
146
|
+
return (_res_data = res.data) === null || _res_data === void 0 ? void 0 : _res_data.token;
|
|
150
147
|
}
|
|
151
148
|
var clearAuthClientToken = function () {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
keysStorage.remove();
|
|
150
|
+
};
|
|
151
|
+
function clearAuthCookies() {
|
|
152
|
+
if (!(typeof document > "u")) {
|
|
153
|
+
var _iteratorNormalCompletion = !0,
|
|
154
|
+
_didIteratorError = !1,
|
|
155
|
+
_iteratorError = void 0;
|
|
156
|
+
try {
|
|
157
|
+
for (var _iterator = authCookieNames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
|
|
158
|
+
var cookieName = _step.value;
|
|
159
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
|
|
160
|
+
var domain = window.location.hostname;
|
|
161
|
+
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${domain}`, domain.startsWith(".") && (document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${domain.slice(1)}`);
|
|
162
|
+
}
|
|
163
|
+
} catch (err) {
|
|
164
|
+
_didIteratorError = !0, _iteratorError = err;
|
|
165
|
+
} finally {
|
|
166
|
+
try {
|
|
167
|
+
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
|
|
168
|
+
} finally {
|
|
169
|
+
if (_didIteratorError) throw _iteratorError;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function clearAllAuth() {
|
|
175
|
+
clearAuthCookies(), clearState();
|
|
176
|
+
}
|
|
177
|
+
var getAuth = function () {
|
|
155
178
|
var state = authState?.value || empty;
|
|
156
179
|
return {
|
|
157
180
|
...state,
|
|
@@ -188,6 +211,7 @@ function createBetterAuthClient(options) {
|
|
|
188
211
|
authClient: proxiedAuthClient,
|
|
189
212
|
setAuthClientToken,
|
|
190
213
|
clearAuthClientToken,
|
|
214
|
+
clearAllAuth,
|
|
191
215
|
useAuth,
|
|
192
216
|
getAuth,
|
|
193
217
|
getValidToken,
|