clearauth 0.3.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/CHANGELOG.md +235 -0
- package/LICENSE +21 -0
- package/README.md +417 -0
- package/dist/auth/handler.d.ts +38 -0
- package/dist/auth/handler.js +483 -0
- package/dist/auth/handler.js.map +1 -0
- package/dist/auth/login.d.ts +69 -0
- package/dist/auth/login.js +103 -0
- package/dist/auth/login.js.map +1 -0
- package/dist/auth/register.d.ts +72 -0
- package/dist/auth/register.js +122 -0
- package/dist/auth/register.js.map +1 -0
- package/dist/auth/reset-password.d.ts +106 -0
- package/dist/auth/reset-password.js +213 -0
- package/dist/auth/reset-password.js.map +1 -0
- package/dist/auth/utils.d.ts +58 -0
- package/dist/auth/utils.js +121 -0
- package/dist/auth/utils.js.map +1 -0
- package/dist/auth/verify-email.d.ts +70 -0
- package/dist/auth/verify-email.js +137 -0
- package/dist/auth/verify-email.js.map +1 -0
- package/dist/createMechAuth.d.ts +178 -0
- package/dist/createMechAuth.js +215 -0
- package/dist/createMechAuth.js.map +1 -0
- package/dist/database/schema.d.ts +135 -0
- package/dist/database/schema.js +37 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/edge.d.ts +4 -0
- package/dist/edge.js +6 -0
- package/dist/edge.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.js +44 -0
- package/dist/errors.js.map +1 -0
- package/dist/handler.d.ts +100 -0
- package/dist/handler.js +213 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.js +40 -0
- package/dist/logger.js.map +1 -0
- package/dist/mech-kysely.d.ts +22 -0
- package/dist/mech-kysely.js +88 -0
- package/dist/mech-kysely.js.map +1 -0
- package/dist/mech-sql-client.d.ts +85 -0
- package/dist/mech-sql-client.js +155 -0
- package/dist/mech-sql-client.js.map +1 -0
- package/dist/node.d.ts +4 -0
- package/dist/node.js +10 -0
- package/dist/node.js.map +1 -0
- package/dist/oauth/arctic-providers.d.ts +60 -0
- package/dist/oauth/arctic-providers.js +94 -0
- package/dist/oauth/arctic-providers.js.map +1 -0
- package/dist/oauth/callbacks.d.ts +155 -0
- package/dist/oauth/callbacks.js +286 -0
- package/dist/oauth/callbacks.js.map +1 -0
- package/dist/oauth/github.d.ts +47 -0
- package/dist/oauth/github.js +136 -0
- package/dist/oauth/github.js.map +1 -0
- package/dist/oauth/google.d.ts +49 -0
- package/dist/oauth/google.js +104 -0
- package/dist/oauth/google.js.map +1 -0
- package/dist/oauth/handler.d.ts +31 -0
- package/dist/oauth/handler.js +277 -0
- package/dist/oauth/handler.js.map +1 -0
- package/dist/password-hasher-argon2.d.ts +7 -0
- package/dist/password-hasher-argon2.js +16 -0
- package/dist/password-hasher-argon2.js.map +1 -0
- package/dist/password-hasher.d.ts +12 -0
- package/dist/password-hasher.js +115 -0
- package/dist/password-hasher.js.map +1 -0
- package/dist/react.d.ts +152 -0
- package/dist/react.js +296 -0
- package/dist/react.js.map +1 -0
- package/dist/types.d.ts +190 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cors.d.ts +65 -0
- package/dist/utils/cors.js +152 -0
- package/dist/utils/cors.js.map +1 -0
- package/dist/utils/normalize-auth-path.d.ts +1 -0
- package/dist/utils/normalize-auth-path.js +8 -0
- package/dist/utils/normalize-auth-path.js.map +1 -0
- package/dist/validation.d.ts +23 -0
- package/dist/validation.js +70 -0
- package/dist/validation.js.map +1 -0
- package/package.json +93 -0
package/dist/react.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* React hooks and utilities for ClearAuth
|
|
4
|
+
*
|
|
5
|
+
* This module provides React hooks for authentication with ClearAuth.
|
|
6
|
+
* Works with any React framework (Next.js, Vite, Create React App, etc.).
|
|
7
|
+
*
|
|
8
|
+
* @module react
|
|
9
|
+
*/
|
|
10
|
+
import { useState, useEffect, useCallback, createContext, useContext } from 'react';
|
|
11
|
+
/**
|
|
12
|
+
* React context for authentication
|
|
13
|
+
*/
|
|
14
|
+
const AuthContext = createContext(undefined);
|
|
15
|
+
/**
|
|
16
|
+
* Authentication provider component
|
|
17
|
+
*
|
|
18
|
+
* Wrap your app with this provider to enable authentication hooks.
|
|
19
|
+
*
|
|
20
|
+
* @param props - Provider props
|
|
21
|
+
* @param props.children - Child components
|
|
22
|
+
* @param props.baseUrl - Base URL for auth API (defaults to "/api/auth")
|
|
23
|
+
* @param props.fetchFn - Custom fetch function (defaults to global fetch)
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* import { AuthProvider } from 'clearauth/react'
|
|
28
|
+
*
|
|
29
|
+
* function App() {
|
|
30
|
+
* return (
|
|
31
|
+
* <AuthProvider baseUrl="/api/auth">
|
|
32
|
+
* <YourApp />
|
|
33
|
+
* </AuthProvider>
|
|
34
|
+
* )
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example With custom base URL
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <AuthProvider baseUrl="https://api.example.com/auth">
|
|
41
|
+
* <YourApp />
|
|
42
|
+
* </AuthProvider>
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function AuthProvider({ children, baseUrl = '/api/auth', fetchFn = fetch, }) {
|
|
46
|
+
const [user, setUser] = useState(null);
|
|
47
|
+
const [loading, setLoading] = useState(true);
|
|
48
|
+
const [error, setError] = useState(null);
|
|
49
|
+
// Helper to make authenticated requests
|
|
50
|
+
const authFetch = useCallback(async (path, options = {}) => {
|
|
51
|
+
const url = `${baseUrl}${path}`;
|
|
52
|
+
const response = await fetchFn(url, {
|
|
53
|
+
...options,
|
|
54
|
+
credentials: 'include', // Include cookies
|
|
55
|
+
headers: {
|
|
56
|
+
'Content-Type': 'application/json',
|
|
57
|
+
...options.headers,
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
62
|
+
throw new Error(errorData.error || errorData.message || 'Request failed');
|
|
63
|
+
}
|
|
64
|
+
return response.json();
|
|
65
|
+
}, [baseUrl, fetchFn]);
|
|
66
|
+
// Check session on mount
|
|
67
|
+
const refresh = useCallback(async () => {
|
|
68
|
+
try {
|
|
69
|
+
setLoading(true);
|
|
70
|
+
setError(null);
|
|
71
|
+
// Session validation would be done server-side via cookie
|
|
72
|
+
// We'll implement a /session endpoint to check current session
|
|
73
|
+
const data = await authFetch('/session');
|
|
74
|
+
setUser(data.user || null);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
setUser(null);
|
|
78
|
+
// Don't set error for unauthenticated state
|
|
79
|
+
if (err.message !== 'Unauthorized') {
|
|
80
|
+
setError(err.message);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
setLoading(false);
|
|
85
|
+
}
|
|
86
|
+
}, [authFetch]);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
refresh();
|
|
89
|
+
}, [refresh]);
|
|
90
|
+
// Sign in with email and password
|
|
91
|
+
const signIn = useCallback(async (email, password) => {
|
|
92
|
+
try {
|
|
93
|
+
setLoading(true);
|
|
94
|
+
setError(null);
|
|
95
|
+
const data = await authFetch('/login', {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
body: JSON.stringify({ email, password }),
|
|
98
|
+
});
|
|
99
|
+
setUser(data.user);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
setError(err.message);
|
|
103
|
+
throw err;
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
setLoading(false);
|
|
107
|
+
}
|
|
108
|
+
}, [authFetch]);
|
|
109
|
+
// Sign up with email and password
|
|
110
|
+
const signUp = useCallback(async (email, password, name) => {
|
|
111
|
+
try {
|
|
112
|
+
setLoading(true);
|
|
113
|
+
setError(null);
|
|
114
|
+
const data = await authFetch('/register', {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
body: JSON.stringify({ email, password, name }),
|
|
117
|
+
});
|
|
118
|
+
setUser(data.user);
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
setError(err.message);
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
setLoading(false);
|
|
126
|
+
}
|
|
127
|
+
}, [authFetch]);
|
|
128
|
+
// Sign out
|
|
129
|
+
const signOut = useCallback(async () => {
|
|
130
|
+
try {
|
|
131
|
+
setLoading(true);
|
|
132
|
+
setError(null);
|
|
133
|
+
await authFetch('/logout', { method: 'POST' });
|
|
134
|
+
setUser(null);
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
setError(err.message);
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
setLoading(false);
|
|
142
|
+
}
|
|
143
|
+
}, [authFetch]);
|
|
144
|
+
// OAuth login helpers
|
|
145
|
+
const loginWithGitHub = useCallback(() => {
|
|
146
|
+
window.location.href = `${baseUrl}/github/login`;
|
|
147
|
+
}, [baseUrl]);
|
|
148
|
+
const loginWithGoogle = useCallback(() => {
|
|
149
|
+
window.location.href = `${baseUrl}/google/login`;
|
|
150
|
+
}, [baseUrl]);
|
|
151
|
+
// Password reset
|
|
152
|
+
const requestPasswordReset = useCallback(async (email) => {
|
|
153
|
+
try {
|
|
154
|
+
setError(null);
|
|
155
|
+
await authFetch('/request-reset', {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
body: JSON.stringify({ email }),
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
setError(err.message);
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
}, [authFetch]);
|
|
165
|
+
const resetPassword = useCallback(async (token, newPassword) => {
|
|
166
|
+
try {
|
|
167
|
+
setError(null);
|
|
168
|
+
await authFetch('/reset-password', {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
body: JSON.stringify({ token, newPassword }),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
setError(err.message);
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
}, [authFetch]);
|
|
178
|
+
// Email verification
|
|
179
|
+
const verifyEmail = useCallback(async (token) => {
|
|
180
|
+
try {
|
|
181
|
+
setError(null);
|
|
182
|
+
await authFetch('/verify-email', {
|
|
183
|
+
method: 'POST',
|
|
184
|
+
body: JSON.stringify({ token }),
|
|
185
|
+
});
|
|
186
|
+
await refresh(); // Refresh to get updated email_verified status
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
setError(err.message);
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
}, [authFetch, refresh]);
|
|
193
|
+
const resendVerification = useCallback(async (email) => {
|
|
194
|
+
try {
|
|
195
|
+
setError(null);
|
|
196
|
+
await authFetch('/resend-verification', {
|
|
197
|
+
method: 'POST',
|
|
198
|
+
body: JSON.stringify({ email }),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
setError(err.message);
|
|
203
|
+
throw err;
|
|
204
|
+
}
|
|
205
|
+
}, [authFetch]);
|
|
206
|
+
const value = {
|
|
207
|
+
user,
|
|
208
|
+
loading,
|
|
209
|
+
error,
|
|
210
|
+
signIn,
|
|
211
|
+
signUp,
|
|
212
|
+
signOut,
|
|
213
|
+
loginWithGitHub,
|
|
214
|
+
loginWithGoogle,
|
|
215
|
+
requestPasswordReset,
|
|
216
|
+
resetPassword,
|
|
217
|
+
verifyEmail,
|
|
218
|
+
resendVerification,
|
|
219
|
+
refresh,
|
|
220
|
+
};
|
|
221
|
+
return _jsx(AuthContext.Provider, { value: value, children: children });
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Hook to access authentication state and actions
|
|
225
|
+
*
|
|
226
|
+
* Must be used within an AuthProvider.
|
|
227
|
+
*
|
|
228
|
+
* @returns Auth state and actions
|
|
229
|
+
* @throws Error if used outside AuthProvider
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```tsx
|
|
233
|
+
* function LoginForm() {
|
|
234
|
+
* const { signIn, loading, error } = useAuth()
|
|
235
|
+
*
|
|
236
|
+
* const handleSubmit = async (e) => {
|
|
237
|
+
* e.preventDefault()
|
|
238
|
+
* await signIn(email, password)
|
|
239
|
+
* }
|
|
240
|
+
*
|
|
241
|
+
* return <form onSubmit={handleSubmit}>...</form>
|
|
242
|
+
* }
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
export function useAuth() {
|
|
246
|
+
const context = useContext(AuthContext);
|
|
247
|
+
if (!context) {
|
|
248
|
+
throw new Error('useAuth must be used within an AuthProvider');
|
|
249
|
+
}
|
|
250
|
+
return context;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Hook to access current user
|
|
254
|
+
*
|
|
255
|
+
* Convenience hook that only returns the user object.
|
|
256
|
+
*
|
|
257
|
+
* @returns Current user or null
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```tsx
|
|
261
|
+
* function UserProfile() {
|
|
262
|
+
* const user = useUser()
|
|
263
|
+
*
|
|
264
|
+
* if (!user) return <div>Not logged in</div>
|
|
265
|
+
*
|
|
266
|
+
* return <div>Welcome, {user.name}!</div>
|
|
267
|
+
* }
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
export function useUser() {
|
|
271
|
+
const { user } = useAuth();
|
|
272
|
+
return user;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Hook to check if user is authenticated
|
|
276
|
+
*
|
|
277
|
+
* @returns True if user is authenticated
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```tsx
|
|
281
|
+
* function ProtectedContent() {
|
|
282
|
+
* const isAuthenticated = useIsAuthenticated()
|
|
283
|
+
*
|
|
284
|
+
* if (!isAuthenticated) {
|
|
285
|
+
* return <LoginPrompt />
|
|
286
|
+
* }
|
|
287
|
+
*
|
|
288
|
+
* return <SecretContent />
|
|
289
|
+
* }
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export function useIsAuthenticated() {
|
|
293
|
+
const { user } = useAuth();
|
|
294
|
+
return user !== null;
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for ClearAuth
|
|
3
|
+
*
|
|
4
|
+
* Core configuration types and OAuth-related interfaces for the authentication system.
|
|
5
|
+
*/
|
|
6
|
+
import type { Kysely } from 'kysely';
|
|
7
|
+
import type { Database } from './database/schema.js';
|
|
8
|
+
import type { PasswordHasher } from './password-hasher.js';
|
|
9
|
+
/**
|
|
10
|
+
* OAuth Provider Configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface OAuthProviderConfig {
|
|
13
|
+
clientId: string;
|
|
14
|
+
clientSecret: string;
|
|
15
|
+
redirectUri: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* OAuth Providers Configuration
|
|
19
|
+
*/
|
|
20
|
+
export interface OAuthProvidersConfig {
|
|
21
|
+
github?: OAuthProviderConfig;
|
|
22
|
+
google?: OAuthProviderConfig;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Session Configuration
|
|
26
|
+
*/
|
|
27
|
+
export interface SessionConfig {
|
|
28
|
+
/**
|
|
29
|
+
* Session expiration time in seconds
|
|
30
|
+
* @default 2592000 (30 days)
|
|
31
|
+
*/
|
|
32
|
+
expiresIn?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Cookie configuration
|
|
35
|
+
*/
|
|
36
|
+
cookie?: {
|
|
37
|
+
name?: string;
|
|
38
|
+
sameSite?: 'strict' | 'lax' | 'none';
|
|
39
|
+
httpOnly?: boolean;
|
|
40
|
+
secure?: boolean;
|
|
41
|
+
path?: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Email/Password Configuration
|
|
46
|
+
*/
|
|
47
|
+
export interface EmailPasswordConfig {
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
requireEmailVerification?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Password Validation Configuration
|
|
53
|
+
*/
|
|
54
|
+
export interface PasswordConfig {
|
|
55
|
+
/**
|
|
56
|
+
* Minimum password length
|
|
57
|
+
* @default 8
|
|
58
|
+
*/
|
|
59
|
+
minLength?: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* CORS Configuration
|
|
63
|
+
*/
|
|
64
|
+
export interface CorsConfig {
|
|
65
|
+
/**
|
|
66
|
+
* Allowed origins for CORS requests
|
|
67
|
+
* - Single origin: "https://example.com"
|
|
68
|
+
* - Multiple origins: ["https://example.com", "https://app.example.com"]
|
|
69
|
+
* - Allow all: "*"
|
|
70
|
+
* @default "*"
|
|
71
|
+
*/
|
|
72
|
+
origin?: string | string[];
|
|
73
|
+
/**
|
|
74
|
+
* Whether to allow credentials (cookies, authorization headers)
|
|
75
|
+
* @default true
|
|
76
|
+
*/
|
|
77
|
+
credentials?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Allowed HTTP methods
|
|
80
|
+
* @default ["GET", "POST", "OPTIONS"]
|
|
81
|
+
*/
|
|
82
|
+
methods?: string[];
|
|
83
|
+
/**
|
|
84
|
+
* Allowed headers
|
|
85
|
+
* @default ["Content-Type", "Authorization"]
|
|
86
|
+
*/
|
|
87
|
+
allowedHeaders?: string[];
|
|
88
|
+
/**
|
|
89
|
+
* Exposed headers
|
|
90
|
+
*/
|
|
91
|
+
exposedHeaders?: string[];
|
|
92
|
+
/**
|
|
93
|
+
* Max age for preflight cache (in seconds)
|
|
94
|
+
* @default 86400 (24 hours)
|
|
95
|
+
*/
|
|
96
|
+
maxAge?: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Main ClearAuth Configuration
|
|
100
|
+
*/
|
|
101
|
+
export interface ClearAuthConfig {
|
|
102
|
+
/**
|
|
103
|
+
* Database instance (Kysely)
|
|
104
|
+
*/
|
|
105
|
+
database: Kysely<Database>;
|
|
106
|
+
/**
|
|
107
|
+
* Secret key for session signing
|
|
108
|
+
*/
|
|
109
|
+
secret: string;
|
|
110
|
+
/**
|
|
111
|
+
* Base URL for the application (used for OAuth redirects)
|
|
112
|
+
*/
|
|
113
|
+
baseUrl: string;
|
|
114
|
+
/**
|
|
115
|
+
* OAuth providers configuration
|
|
116
|
+
*/
|
|
117
|
+
oauth?: OAuthProvidersConfig;
|
|
118
|
+
/**
|
|
119
|
+
* Session configuration
|
|
120
|
+
*/
|
|
121
|
+
session?: SessionConfig;
|
|
122
|
+
/**
|
|
123
|
+
* Email/password authentication configuration
|
|
124
|
+
*/
|
|
125
|
+
emailPassword?: EmailPasswordConfig;
|
|
126
|
+
/**
|
|
127
|
+
* Password validation configuration
|
|
128
|
+
*/
|
|
129
|
+
password?: PasswordConfig;
|
|
130
|
+
/**
|
|
131
|
+
* Password hashing implementation
|
|
132
|
+
*/
|
|
133
|
+
passwordHasher?: PasswordHasher;
|
|
134
|
+
/**
|
|
135
|
+
* CORS configuration for browser clients
|
|
136
|
+
*/
|
|
137
|
+
cors?: CorsConfig;
|
|
138
|
+
/**
|
|
139
|
+
* Production mode flag
|
|
140
|
+
*/
|
|
141
|
+
isProduction?: boolean;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Standardized OAuth User Profile
|
|
145
|
+
*
|
|
146
|
+
* Normalized user data from OAuth providers (GitHub, Google, etc.)
|
|
147
|
+
*/
|
|
148
|
+
export interface OAuthUserProfile {
|
|
149
|
+
/** Provider-specific user ID */
|
|
150
|
+
id: string;
|
|
151
|
+
/** User's email address */
|
|
152
|
+
email: string;
|
|
153
|
+
/** User's full name (may be null) */
|
|
154
|
+
name: string | null;
|
|
155
|
+
/** User's avatar URL (may be null) */
|
|
156
|
+
avatar_url: string | null;
|
|
157
|
+
/** Whether email is verified by provider */
|
|
158
|
+
email_verified?: boolean;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* OAuth State Parameter (CSRF protection)
|
|
162
|
+
*/
|
|
163
|
+
export interface OAuthState {
|
|
164
|
+
/** Random state value */
|
|
165
|
+
state: string;
|
|
166
|
+
/** Timestamp when state was created */
|
|
167
|
+
createdAt: number;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* OAuth Callback Result
|
|
171
|
+
*/
|
|
172
|
+
export interface OAuthCallbackResult {
|
|
173
|
+
/** User profile from OAuth provider */
|
|
174
|
+
profile: OAuthUserProfile;
|
|
175
|
+
/** Access token from provider (optional) */
|
|
176
|
+
accessToken?: string;
|
|
177
|
+
/** Refresh token from provider (optional) */
|
|
178
|
+
refreshToken?: string;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Request Context
|
|
182
|
+
*
|
|
183
|
+
* Information about the incoming HTTP request (for session creation)
|
|
184
|
+
*/
|
|
185
|
+
export interface RequestContext {
|
|
186
|
+
/** Client IP address */
|
|
187
|
+
ipAddress?: string;
|
|
188
|
+
/** User agent string */
|
|
189
|
+
userAgent?: string;
|
|
190
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS (Cross-Origin Resource Sharing) Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for handling CORS headers in authentication endpoints.
|
|
5
|
+
* Essential for browser-based clients making cross-origin requests.
|
|
6
|
+
*/
|
|
7
|
+
import type { CorsConfig } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create CORS headers for a response
|
|
10
|
+
*
|
|
11
|
+
* @param request - HTTP request
|
|
12
|
+
* @param config - CORS configuration
|
|
13
|
+
* @returns Headers object with CORS headers
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const headers = createCorsHeaders(request, config.cors)
|
|
18
|
+
* return new Response(body, { headers })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function createCorsHeaders(request: Request, config?: CorsConfig): Headers;
|
|
22
|
+
/**
|
|
23
|
+
* Handle CORS preflight request (OPTIONS)
|
|
24
|
+
*
|
|
25
|
+
* @param request - HTTP OPTIONS request
|
|
26
|
+
* @param config - CORS configuration
|
|
27
|
+
* @returns Response with CORS headers
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* if (request.method === 'OPTIONS') {
|
|
32
|
+
* return handleCorsPreflightRequest(request, config.cors)
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function handleCorsPreflightRequest(request: Request, config?: CorsConfig): Response;
|
|
37
|
+
/**
|
|
38
|
+
* Add CORS headers to an existing response
|
|
39
|
+
*
|
|
40
|
+
* @param response - Original response
|
|
41
|
+
* @param request - HTTP request
|
|
42
|
+
* @param config - CORS configuration
|
|
43
|
+
* @returns Response with CORS headers added
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const response = await handleAuthRequest(request, config)
|
|
48
|
+
* return addCorsHeaders(response, request, config.cors)
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function addCorsHeaders(response: Response, request: Request, config?: CorsConfig): Response;
|
|
52
|
+
/**
|
|
53
|
+
* Wrap a request handler with CORS support
|
|
54
|
+
*
|
|
55
|
+
* @param handler - Original request handler
|
|
56
|
+
* @param config - CORS configuration
|
|
57
|
+
* @returns Wrapped handler with CORS support
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const handleWithCors = withCors(handleAuthRequest, config.cors)
|
|
62
|
+
* return handleWithCors(request, config)
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function withCors(handler: (request: Request, config: any) => Promise<Response>, corsConfig?: CorsConfig): (request: Request, config: any) => Promise<Response>;
|