@reauth-dev/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/{chunk-JX2J36FS.mjs → chunk-DMNMTW2C.mjs} +96 -29
- package/dist/chunk-EY5LQCDG.mjs +6 -0
- package/dist/index.d.mts +22 -15
- package/dist/index.d.ts +22 -15
- package/dist/index.js +95 -29
- package/dist/index.mjs +2 -1
- package/dist/react/index.d.mts +15 -5
- package/dist/react/index.d.ts +15 -5
- package/dist/react/index.js +118 -34
- package/dist/react/index.mjs +27 -8
- package/dist/server.d.mts +20 -2
- package/dist/server.d.ts +20 -2
- package/dist/server.js +57 -12
- package/dist/server.mjs +53 -11
- package/dist/{types-D8oOYbeC.d.mts → types-BqZzje-y.d.mts} +21 -3
- package/dist/{types-D8oOYbeC.d.ts → types-BqZzje-y.d.ts} +21 -3
- package/dist/webhooks.js +7 -3
- package/dist/webhooks.mjs +7 -3
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -26,9 +26,27 @@ __export(src_exports, {
|
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(src_exports);
|
|
28
28
|
|
|
29
|
+
// src/types.ts
|
|
30
|
+
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
31
|
+
|
|
29
32
|
// src/client.ts
|
|
33
|
+
function assertHttpsUrl(url) {
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = new URL(url);
|
|
37
|
+
} catch {
|
|
38
|
+
throw new Error("URL must use HTTPS");
|
|
39
|
+
}
|
|
40
|
+
if (parsed.protocol !== "https:") {
|
|
41
|
+
throw new Error("URL must use HTTPS");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
30
44
|
function createReauthClient(config) {
|
|
31
45
|
const { domain } = config;
|
|
46
|
+
if (config.timeout !== void 0 && (!Number.isFinite(config.timeout) || config.timeout <= 0)) {
|
|
47
|
+
throw new Error("timeout must be a positive finite number in milliseconds");
|
|
48
|
+
}
|
|
49
|
+
const timeoutMs = config.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
32
50
|
const baseUrl = `https://reauth.${domain}/api/public`;
|
|
33
51
|
return {
|
|
34
52
|
/**
|
|
@@ -47,35 +65,47 @@ function createReauthClient(config) {
|
|
|
47
65
|
*/
|
|
48
66
|
async getSession() {
|
|
49
67
|
const res = await fetch(`${baseUrl}/auth/session`, {
|
|
50
|
-
credentials: "include"
|
|
68
|
+
credentials: "include",
|
|
69
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
51
70
|
});
|
|
71
|
+
if (!res.ok) {
|
|
72
|
+
throw new Error(`Failed to get session: ${res.status}`);
|
|
73
|
+
}
|
|
52
74
|
return res.json();
|
|
53
75
|
},
|
|
54
76
|
/**
|
|
55
77
|
* Refresh the access token using the refresh token.
|
|
56
78
|
* Call this when getSession() returns valid: false but no error_code.
|
|
57
|
-
* @
|
|
79
|
+
* @throws Error on failed refresh (401) or server error
|
|
58
80
|
*/
|
|
59
81
|
async refresh() {
|
|
60
82
|
const res = await fetch(`${baseUrl}/auth/refresh`, {
|
|
61
83
|
method: "POST",
|
|
62
|
-
credentials: "include"
|
|
84
|
+
credentials: "include",
|
|
85
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
63
86
|
});
|
|
64
|
-
|
|
87
|
+
if (!res.ok) {
|
|
88
|
+
throw new Error(`Failed to refresh: ${res.status}`);
|
|
89
|
+
}
|
|
65
90
|
},
|
|
66
91
|
/**
|
|
67
92
|
* Get an access token for Bearer authentication.
|
|
68
93
|
* Use this when calling your own API that uses local token verification.
|
|
69
94
|
*
|
|
70
|
-
* @returns TokenResponse with access token, or null if not authenticated
|
|
95
|
+
* @returns TokenResponse with access token, or null if not authenticated or network unreachable
|
|
96
|
+
* @throws Error on server errors (non-401 HTTP status codes) or request timeout
|
|
71
97
|
*
|
|
72
98
|
* @example
|
|
73
99
|
* ```typescript
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
100
|
+
* try {
|
|
101
|
+
* const tokenResponse = await reauth.getToken();
|
|
102
|
+
* if (tokenResponse) {
|
|
103
|
+
* fetch('/api/data', {
|
|
104
|
+
* headers: { Authorization: `Bearer ${tokenResponse.accessToken}` }
|
|
105
|
+
* });
|
|
106
|
+
* }
|
|
107
|
+
* } catch (err) {
|
|
108
|
+
* // Server error or timeout — do not log the user out
|
|
79
109
|
* }
|
|
80
110
|
* ```
|
|
81
111
|
*/
|
|
@@ -83,7 +113,8 @@ function createReauthClient(config) {
|
|
|
83
113
|
try {
|
|
84
114
|
const res = await fetch(`${baseUrl}/auth/token`, {
|
|
85
115
|
method: "GET",
|
|
86
|
-
credentials: "include"
|
|
116
|
+
credentials: "include",
|
|
117
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
87
118
|
});
|
|
88
119
|
if (!res.ok) {
|
|
89
120
|
if (res.status === 401) return null;
|
|
@@ -95,29 +126,38 @@ function createReauthClient(config) {
|
|
|
95
126
|
expiresIn: data.expires_in,
|
|
96
127
|
tokenType: data.token_type
|
|
97
128
|
};
|
|
98
|
-
} catch {
|
|
99
|
-
return null;
|
|
129
|
+
} catch (err) {
|
|
130
|
+
if (err instanceof TypeError) return null;
|
|
131
|
+
throw err;
|
|
100
132
|
}
|
|
101
133
|
},
|
|
102
134
|
/**
|
|
103
135
|
* Log out the user by clearing all session cookies.
|
|
136
|
+
* @throws Error on server error
|
|
104
137
|
*/
|
|
105
138
|
async logout() {
|
|
106
|
-
await fetch(`${baseUrl}/auth/logout`, {
|
|
139
|
+
const res = await fetch(`${baseUrl}/auth/logout`, {
|
|
107
140
|
method: "POST",
|
|
108
|
-
credentials: "include"
|
|
141
|
+
credentials: "include",
|
|
142
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
109
143
|
});
|
|
144
|
+
if (!res.ok) {
|
|
145
|
+
throw new Error(`Failed to logout: ${res.status}`);
|
|
146
|
+
}
|
|
110
147
|
},
|
|
111
148
|
/**
|
|
112
149
|
* Delete the user's own account (self-service).
|
|
113
|
-
* @
|
|
150
|
+
* @throws Error on permission denied or server error
|
|
114
151
|
*/
|
|
115
152
|
async deleteAccount() {
|
|
116
153
|
const res = await fetch(`${baseUrl}/auth/account`, {
|
|
117
154
|
method: "DELETE",
|
|
118
|
-
credentials: "include"
|
|
155
|
+
credentials: "include",
|
|
156
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
119
157
|
});
|
|
120
|
-
|
|
158
|
+
if (!res.ok) {
|
|
159
|
+
throw new Error(`Failed to delete account: ${res.status}`);
|
|
160
|
+
}
|
|
121
161
|
},
|
|
122
162
|
// ========================================================================
|
|
123
163
|
// Billing Methods
|
|
@@ -125,12 +165,16 @@ function createReauthClient(config) {
|
|
|
125
165
|
/**
|
|
126
166
|
* Get available subscription plans for the domain.
|
|
127
167
|
* Only returns public plans sorted by display order.
|
|
168
|
+
* @throws Error on server error
|
|
128
169
|
*/
|
|
129
170
|
async getPlans() {
|
|
130
171
|
const res = await fetch(`${baseUrl}/billing/plans`, {
|
|
131
|
-
credentials: "include"
|
|
172
|
+
credentials: "include",
|
|
173
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
132
174
|
});
|
|
133
|
-
if (!res.ok)
|
|
175
|
+
if (!res.ok) {
|
|
176
|
+
throw new Error(`Failed to get plans: ${res.status}`);
|
|
177
|
+
}
|
|
134
178
|
const data = await res.json();
|
|
135
179
|
return data.map(
|
|
136
180
|
(p) => ({
|
|
@@ -143,8 +187,17 @@ function createReauthClient(config) {
|
|
|
143
187
|
interval: p.interval,
|
|
144
188
|
intervalCount: p.interval_count,
|
|
145
189
|
trialDays: p.trial_days,
|
|
146
|
-
features: p.features
|
|
147
|
-
|
|
190
|
+
features: p.features.map((f) => ({
|
|
191
|
+
code: f.code,
|
|
192
|
+
name: f.name,
|
|
193
|
+
featureType: f.feature_type,
|
|
194
|
+
numericValue: f.numeric_value,
|
|
195
|
+
unitLabel: f.unit_label
|
|
196
|
+
})),
|
|
197
|
+
displayOrder: p.display_order,
|
|
198
|
+
creditsAmount: p.credits_amount,
|
|
199
|
+
planType: p.plan_type,
|
|
200
|
+
contactUrl: p.contact_url
|
|
148
201
|
})
|
|
149
202
|
);
|
|
150
203
|
},
|
|
@@ -153,8 +206,12 @@ function createReauthClient(config) {
|
|
|
153
206
|
*/
|
|
154
207
|
async getSubscription() {
|
|
155
208
|
const res = await fetch(`${baseUrl}/billing/subscription`, {
|
|
156
|
-
credentials: "include"
|
|
209
|
+
credentials: "include",
|
|
210
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
157
211
|
});
|
|
212
|
+
if (!res.ok) {
|
|
213
|
+
throw new Error(`Failed to get subscription: ${res.status}`);
|
|
214
|
+
}
|
|
158
215
|
const data = await res.json();
|
|
159
216
|
return {
|
|
160
217
|
id: data.id,
|
|
@@ -178,6 +235,7 @@ function createReauthClient(config) {
|
|
|
178
235
|
method: "POST",
|
|
179
236
|
headers: { "Content-Type": "application/json" },
|
|
180
237
|
credentials: "include",
|
|
238
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
181
239
|
body: JSON.stringify({
|
|
182
240
|
plan_code: planCode,
|
|
183
241
|
success_url: successUrl,
|
|
@@ -206,6 +264,7 @@ function createReauthClient(config) {
|
|
|
206
264
|
currentUrl,
|
|
207
265
|
currentUrl
|
|
208
266
|
);
|
|
267
|
+
assertHttpsUrl(checkoutUrl);
|
|
209
268
|
window.location.href = checkoutUrl;
|
|
210
269
|
},
|
|
211
270
|
/**
|
|
@@ -220,6 +279,7 @@ function createReauthClient(config) {
|
|
|
220
279
|
method: "POST",
|
|
221
280
|
headers: { "Content-Type": "application/json" },
|
|
222
281
|
credentials: "include",
|
|
282
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
223
283
|
body: JSON.stringify({
|
|
224
284
|
return_url: returnUrl || window.location.href
|
|
225
285
|
})
|
|
@@ -228,18 +288,22 @@ function createReauthClient(config) {
|
|
|
228
288
|
throw new Error("Failed to open billing portal");
|
|
229
289
|
}
|
|
230
290
|
const data = await res.json();
|
|
291
|
+
assertHttpsUrl(data.portal_url);
|
|
231
292
|
window.location.href = data.portal_url;
|
|
232
293
|
},
|
|
233
294
|
/**
|
|
234
295
|
* Cancel the user's subscription at period end.
|
|
235
|
-
* @
|
|
296
|
+
* @throws Error on failure or server error
|
|
236
297
|
*/
|
|
237
298
|
async cancelSubscription() {
|
|
238
299
|
const res = await fetch(`${baseUrl}/billing/cancel`, {
|
|
239
300
|
method: "POST",
|
|
240
|
-
credentials: "include"
|
|
301
|
+
credentials: "include",
|
|
302
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
241
303
|
});
|
|
242
|
-
|
|
304
|
+
if (!res.ok) {
|
|
305
|
+
throw new Error(`Failed to cancel subscription: ${res.status}`);
|
|
306
|
+
}
|
|
243
307
|
},
|
|
244
308
|
// ========================================================================
|
|
245
309
|
// Balance Methods
|
|
@@ -250,13 +314,15 @@ function createReauthClient(config) {
|
|
|
250
314
|
*/
|
|
251
315
|
async getBalance() {
|
|
252
316
|
const res = await fetch(`${baseUrl}/balance`, {
|
|
253
|
-
credentials: "include"
|
|
317
|
+
credentials: "include",
|
|
318
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
254
319
|
});
|
|
255
320
|
if (!res.ok) {
|
|
256
321
|
if (res.status === 401) throw new Error("Not authenticated");
|
|
257
322
|
throw new Error(`Failed to get balance: ${res.status}`);
|
|
258
323
|
}
|
|
259
|
-
|
|
324
|
+
const data = await res.json();
|
|
325
|
+
return { balance: data.balance };
|
|
260
326
|
},
|
|
261
327
|
/**
|
|
262
328
|
* Get the current user's balance transaction history.
|
|
@@ -270,7 +336,7 @@ function createReauthClient(config) {
|
|
|
270
336
|
const qs = params.toString();
|
|
271
337
|
const res = await fetch(
|
|
272
338
|
`${baseUrl}/balance/transactions${qs ? `?${qs}` : ""}`,
|
|
273
|
-
{ credentials: "include" }
|
|
339
|
+
{ credentials: "include", signal: AbortSignal.timeout(timeoutMs) }
|
|
274
340
|
);
|
|
275
341
|
if (!res.ok) {
|
|
276
342
|
if (res.status === 401) throw new Error("Not authenticated");
|
package/dist/index.mjs
CHANGED
package/dist/react/index.d.mts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import { R as ReauthConfig, c as User } from '../types-
|
|
1
|
+
import { R as ReauthConfig, c as User } from '../types-BqZzje-y.mjs';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
|
|
5
|
+
type UseAuthOptions = ReauthConfig & {
|
|
6
|
+
/**
|
|
7
|
+
* Interval in milliseconds to refresh the session. Set to 0 to disable.
|
|
8
|
+
* Default: 5 minutes (300000ms)
|
|
9
|
+
*/
|
|
10
|
+
refreshInterval?: number;
|
|
11
|
+
};
|
|
5
12
|
/**
|
|
6
13
|
* React hook for authentication state management.
|
|
7
14
|
*
|
|
8
15
|
* @example
|
|
9
16
|
* ```typescript
|
|
10
17
|
* function MyComponent() {
|
|
11
|
-
* const { user, loading, login, logout } = useAuth({
|
|
18
|
+
* const { user, loading, login, logout } = useAuth({
|
|
19
|
+
* domain: 'yourdomain.com',
|
|
20
|
+
* refreshInterval: 60000, // Refresh every minute (optional, default: 5 min)
|
|
21
|
+
* });
|
|
12
22
|
*
|
|
13
23
|
* if (loading) return <div>Loading...</div>;
|
|
14
24
|
* if (!user) return <button onClick={login}>Sign in</button>;
|
|
@@ -22,7 +32,7 @@ import { ReactNode } from 'react';
|
|
|
22
32
|
* }
|
|
23
33
|
* ```
|
|
24
34
|
*/
|
|
25
|
-
declare function useAuth(config:
|
|
35
|
+
declare function useAuth(config: UseAuthOptions): {
|
|
26
36
|
login: () => void;
|
|
27
37
|
logout: () => Promise<void>;
|
|
28
38
|
refetch: () => Promise<void>;
|
|
@@ -44,7 +54,7 @@ type AuthContextType = {
|
|
|
44
54
|
refetch: () => Promise<void>;
|
|
45
55
|
};
|
|
46
56
|
type AuthProviderProps = {
|
|
47
|
-
config:
|
|
57
|
+
config: UseAuthOptions;
|
|
48
58
|
children: ReactNode;
|
|
49
59
|
};
|
|
50
60
|
/**
|
|
@@ -120,4 +130,4 @@ type ProtectedRouteProps = {
|
|
|
120
130
|
*/
|
|
121
131
|
declare function ProtectedRoute({ children, fallback, onUnauthenticated, onWaitlist, }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
|
|
122
132
|
|
|
123
|
-
export { AuthProvider, ProtectedRoute, useAuth, useAuthContext };
|
|
133
|
+
export { AuthProvider, ProtectedRoute, type UseAuthOptions, useAuth, useAuthContext };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import { R as ReauthConfig, c as User } from '../types-
|
|
1
|
+
import { R as ReauthConfig, c as User } from '../types-BqZzje-y.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
4
|
|
|
5
|
+
type UseAuthOptions = ReauthConfig & {
|
|
6
|
+
/**
|
|
7
|
+
* Interval in milliseconds to refresh the session. Set to 0 to disable.
|
|
8
|
+
* Default: 5 minutes (300000ms)
|
|
9
|
+
*/
|
|
10
|
+
refreshInterval?: number;
|
|
11
|
+
};
|
|
5
12
|
/**
|
|
6
13
|
* React hook for authentication state management.
|
|
7
14
|
*
|
|
8
15
|
* @example
|
|
9
16
|
* ```typescript
|
|
10
17
|
* function MyComponent() {
|
|
11
|
-
* const { user, loading, login, logout } = useAuth({
|
|
18
|
+
* const { user, loading, login, logout } = useAuth({
|
|
19
|
+
* domain: 'yourdomain.com',
|
|
20
|
+
* refreshInterval: 60000, // Refresh every minute (optional, default: 5 min)
|
|
21
|
+
* });
|
|
12
22
|
*
|
|
13
23
|
* if (loading) return <div>Loading...</div>;
|
|
14
24
|
* if (!user) return <button onClick={login}>Sign in</button>;
|
|
@@ -22,7 +32,7 @@ import { ReactNode } from 'react';
|
|
|
22
32
|
* }
|
|
23
33
|
* ```
|
|
24
34
|
*/
|
|
25
|
-
declare function useAuth(config:
|
|
35
|
+
declare function useAuth(config: UseAuthOptions): {
|
|
26
36
|
login: () => void;
|
|
27
37
|
logout: () => Promise<void>;
|
|
28
38
|
refetch: () => Promise<void>;
|
|
@@ -44,7 +54,7 @@ type AuthContextType = {
|
|
|
44
54
|
refetch: () => Promise<void>;
|
|
45
55
|
};
|
|
46
56
|
type AuthProviderProps = {
|
|
47
|
-
config:
|
|
57
|
+
config: UseAuthOptions;
|
|
48
58
|
children: ReactNode;
|
|
49
59
|
};
|
|
50
60
|
/**
|
|
@@ -120,4 +130,4 @@ type ProtectedRouteProps = {
|
|
|
120
130
|
*/
|
|
121
131
|
declare function ProtectedRoute({ children, fallback, onUnauthenticated, onWaitlist, }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
|
|
122
132
|
|
|
123
|
-
export { AuthProvider, ProtectedRoute, useAuth, useAuthContext };
|
|
133
|
+
export { AuthProvider, ProtectedRoute, type UseAuthOptions, useAuth, useAuthContext };
|