hylekit 1.0.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.cjs ADDED
@@ -0,0 +1,705 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DEFAULT_CONFIG: () => DEFAULT_CONFIG,
24
+ account: () => account,
25
+ accountRelations: () => accountRelations,
26
+ createAuth: () => createAuth,
27
+ createNextClient: () => createNextClient,
28
+ createSvelteKitClient: () => createSvelteKitClient,
29
+ nextClient: () => nextClient,
30
+ oauthAccessToken: () => oauthAccessToken,
31
+ oauthAccessTokenRelations: () => oauthAccessTokenRelations,
32
+ oauthApplication: () => oauthApplication,
33
+ oauthApplicationRelations: () => oauthApplicationRelations,
34
+ oauthConsent: () => oauthConsent,
35
+ oauthConsentRelations: () => oauthConsentRelations,
36
+ session: () => session,
37
+ sessionRelations: () => sessionRelations,
38
+ svelteClient: () => svelteClient,
39
+ user: () => user,
40
+ userRelations: () => userRelations,
41
+ verification: () => verification
42
+ });
43
+ module.exports = __toCommonJS(index_exports);
44
+
45
+ // src/auth.ts
46
+ var import_better_auth = require("better-auth");
47
+ var import_drizzle = require("better-auth/adapters/drizzle");
48
+
49
+ // src/schema.ts
50
+ var schema_exports = {};
51
+ __export(schema_exports, {
52
+ account: () => account,
53
+ accountRelations: () => accountRelations,
54
+ oauthAccessToken: () => oauthAccessToken,
55
+ oauthAccessTokenRelations: () => oauthAccessTokenRelations,
56
+ oauthApplication: () => oauthApplication,
57
+ oauthApplicationRelations: () => oauthApplicationRelations,
58
+ oauthConsent: () => oauthConsent,
59
+ oauthConsentRelations: () => oauthConsentRelations,
60
+ session: () => session,
61
+ sessionRelations: () => sessionRelations,
62
+ user: () => user,
63
+ userRelations: () => userRelations,
64
+ verification: () => verification
65
+ });
66
+ var import_drizzle_orm = require("drizzle-orm");
67
+ var import_sqlite_core = require("drizzle-orm/sqlite-core");
68
+ var user = (0, import_sqlite_core.sqliteTable)("user", {
69
+ id: (0, import_sqlite_core.text)("id").primaryKey(),
70
+ name: (0, import_sqlite_core.text)("name").notNull(),
71
+ email: (0, import_sqlite_core.text)("email").notNull().unique(),
72
+ emailVerified: (0, import_sqlite_core.integer)("email_verified", { mode: "boolean" }).default(false).notNull(),
73
+ image: (0, import_sqlite_core.text)("image"),
74
+ createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).default(import_drizzle_orm.sql`(cast(unixepoch('subsecond') * 1000 as integer))`).notNull(),
75
+ updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }).default(import_drizzle_orm.sql`(cast(unixepoch('subsecond') * 1000 as integer))`).$onUpdate(() => /* @__PURE__ */ new Date()).notNull()
76
+ });
77
+ var session = (0, import_sqlite_core.sqliteTable)(
78
+ "session",
79
+ {
80
+ id: (0, import_sqlite_core.text)("id").primaryKey(),
81
+ expiresAt: (0, import_sqlite_core.integer)("expires_at", { mode: "timestamp_ms" }).notNull(),
82
+ token: (0, import_sqlite_core.text)("token").notNull().unique(),
83
+ createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).default(import_drizzle_orm.sql`(cast(unixepoch('subsecond') * 1000 as integer))`).notNull(),
84
+ updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }).$onUpdate(() => /* @__PURE__ */ new Date()).notNull(),
85
+ ipAddress: (0, import_sqlite_core.text)("ip_address"),
86
+ userAgent: (0, import_sqlite_core.text)("user_agent"),
87
+ userId: (0, import_sqlite_core.text)("user_id").notNull().references(() => user.id, { onDelete: "cascade" })
88
+ },
89
+ (table) => [(0, import_sqlite_core.index)("session_userId_idx").on(table.userId)]
90
+ );
91
+ var account = (0, import_sqlite_core.sqliteTable)(
92
+ "account",
93
+ {
94
+ id: (0, import_sqlite_core.text)("id").primaryKey(),
95
+ accountId: (0, import_sqlite_core.text)("account_id").notNull(),
96
+ providerId: (0, import_sqlite_core.text)("provider_id").notNull(),
97
+ userId: (0, import_sqlite_core.text)("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
98
+ accessToken: (0, import_sqlite_core.text)("access_token"),
99
+ refreshToken: (0, import_sqlite_core.text)("refresh_token"),
100
+ idToken: (0, import_sqlite_core.text)("id_token"),
101
+ accessTokenExpiresAt: (0, import_sqlite_core.integer)("access_token_expires_at", {
102
+ mode: "timestamp_ms"
103
+ }),
104
+ refreshTokenExpiresAt: (0, import_sqlite_core.integer)("refresh_token_expires_at", {
105
+ mode: "timestamp_ms"
106
+ }),
107
+ scope: (0, import_sqlite_core.text)("scope"),
108
+ password: (0, import_sqlite_core.text)("password"),
109
+ createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).default(import_drizzle_orm.sql`(cast(unixepoch('subsecond') * 1000 as integer))`).notNull(),
110
+ updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }).$onUpdate(() => /* @__PURE__ */ new Date()).notNull()
111
+ },
112
+ (table) => [(0, import_sqlite_core.index)("account_userId_idx").on(table.userId)]
113
+ );
114
+ var verification = (0, import_sqlite_core.sqliteTable)(
115
+ "verification",
116
+ {
117
+ id: (0, import_sqlite_core.text)("id").primaryKey(),
118
+ identifier: (0, import_sqlite_core.text)("identifier").notNull(),
119
+ value: (0, import_sqlite_core.text)("value").notNull(),
120
+ expiresAt: (0, import_sqlite_core.integer)("expires_at", { mode: "timestamp_ms" }).notNull(),
121
+ createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }).default(import_drizzle_orm.sql`(cast(unixepoch('subsecond') * 1000 as integer))`).notNull(),
122
+ updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }).default(import_drizzle_orm.sql`(cast(unixepoch('subsecond') * 1000 as integer))`).$onUpdate(() => /* @__PURE__ */ new Date()).notNull()
123
+ },
124
+ (table) => [(0, import_sqlite_core.index)("verification_identifier_idx").on(table.identifier)]
125
+ );
126
+ var oauthApplication = (0, import_sqlite_core.sqliteTable)(
127
+ "oauth_application",
128
+ {
129
+ id: (0, import_sqlite_core.text)("id").primaryKey(),
130
+ name: (0, import_sqlite_core.text)("name"),
131
+ icon: (0, import_sqlite_core.text)("icon"),
132
+ metadata: (0, import_sqlite_core.text)("metadata"),
133
+ clientId: (0, import_sqlite_core.text)("client_id").unique(),
134
+ clientSecret: (0, import_sqlite_core.text)("client_secret"),
135
+ redirectUrls: (0, import_sqlite_core.text)("redirect_urls"),
136
+ type: (0, import_sqlite_core.text)("type"),
137
+ disabled: (0, import_sqlite_core.integer)("disabled", { mode: "boolean" }).default(false),
138
+ userId: (0, import_sqlite_core.text)("user_id").references(() => user.id, { onDelete: "cascade" }),
139
+ createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }),
140
+ updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" })
141
+ },
142
+ (table) => [(0, import_sqlite_core.index)("oauthApplication_userId_idx").on(table.userId)]
143
+ );
144
+ var oauthAccessToken = (0, import_sqlite_core.sqliteTable)(
145
+ "oauth_access_token",
146
+ {
147
+ id: (0, import_sqlite_core.text)("id").primaryKey(),
148
+ accessToken: (0, import_sqlite_core.text)("access_token").unique(),
149
+ refreshToken: (0, import_sqlite_core.text)("refresh_token").unique(),
150
+ accessTokenExpiresAt: (0, import_sqlite_core.integer)("access_token_expires_at", {
151
+ mode: "timestamp_ms"
152
+ }),
153
+ refreshTokenExpiresAt: (0, import_sqlite_core.integer)("refresh_token_expires_at", {
154
+ mode: "timestamp_ms"
155
+ }),
156
+ clientId: (0, import_sqlite_core.text)("client_id").references(() => oauthApplication.clientId, {
157
+ onDelete: "cascade"
158
+ }),
159
+ userId: (0, import_sqlite_core.text)("user_id").references(() => user.id, { onDelete: "cascade" }),
160
+ scopes: (0, import_sqlite_core.text)("scopes"),
161
+ createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }),
162
+ updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" })
163
+ },
164
+ (table) => [
165
+ (0, import_sqlite_core.index)("oauthAccessToken_clientId_idx").on(table.clientId),
166
+ (0, import_sqlite_core.index)("oauthAccessToken_userId_idx").on(table.userId)
167
+ ]
168
+ );
169
+ var oauthConsent = (0, import_sqlite_core.sqliteTable)(
170
+ "oauth_consent",
171
+ {
172
+ id: (0, import_sqlite_core.text)("id").primaryKey(),
173
+ clientId: (0, import_sqlite_core.text)("client_id").references(() => oauthApplication.clientId, {
174
+ onDelete: "cascade"
175
+ }),
176
+ userId: (0, import_sqlite_core.text)("user_id").references(() => user.id, { onDelete: "cascade" }),
177
+ scopes: (0, import_sqlite_core.text)("scopes"),
178
+ createdAt: (0, import_sqlite_core.integer)("created_at", { mode: "timestamp_ms" }),
179
+ updatedAt: (0, import_sqlite_core.integer)("updated_at", { mode: "timestamp_ms" }),
180
+ consentGiven: (0, import_sqlite_core.integer)("consent_given", { mode: "boolean" })
181
+ },
182
+ (table) => [
183
+ (0, import_sqlite_core.index)("oauthConsent_clientId_idx").on(table.clientId),
184
+ (0, import_sqlite_core.index)("oauthConsent_userId_idx").on(table.userId)
185
+ ]
186
+ );
187
+ var userRelations = (0, import_drizzle_orm.relations)(user, ({ many }) => ({
188
+ sessions: many(session),
189
+ accounts: many(account),
190
+ oauthApplications: many(oauthApplication),
191
+ oauthAccessTokens: many(oauthAccessToken),
192
+ oauthConsents: many(oauthConsent)
193
+ }));
194
+ var sessionRelations = (0, import_drizzle_orm.relations)(session, ({ one }) => ({
195
+ user: one(user, {
196
+ fields: [session.userId],
197
+ references: [user.id]
198
+ })
199
+ }));
200
+ var accountRelations = (0, import_drizzle_orm.relations)(account, ({ one }) => ({
201
+ user: one(user, {
202
+ fields: [account.userId],
203
+ references: [user.id]
204
+ })
205
+ }));
206
+ var oauthApplicationRelations = (0, import_drizzle_orm.relations)(
207
+ oauthApplication,
208
+ ({ one, many }) => ({
209
+ user: one(user, {
210
+ fields: [oauthApplication.userId],
211
+ references: [user.id]
212
+ }),
213
+ oauthAccessTokens: many(oauthAccessToken),
214
+ oauthConsents: many(oauthConsent)
215
+ })
216
+ );
217
+ var oauthAccessTokenRelations = (0, import_drizzle_orm.relations)(
218
+ oauthAccessToken,
219
+ ({ one }) => ({
220
+ oauthApplication: one(oauthApplication, {
221
+ fields: [oauthAccessToken.clientId],
222
+ references: [oauthApplication.clientId]
223
+ }),
224
+ user: one(user, {
225
+ fields: [oauthAccessToken.userId],
226
+ references: [user.id]
227
+ })
228
+ })
229
+ );
230
+ var oauthConsentRelations = (0, import_drizzle_orm.relations)(oauthConsent, ({ one }) => ({
231
+ oauthApplication: one(oauthApplication, {
232
+ fields: [oauthConsent.clientId],
233
+ references: [oauthApplication.clientId]
234
+ }),
235
+ user: one(user, {
236
+ fields: [oauthConsent.userId],
237
+ references: [user.id]
238
+ })
239
+ }));
240
+
241
+ // src/auth.ts
242
+ var createAuth = (db, config) => {
243
+ return (0, import_better_auth.betterAuth)({
244
+ database: (0, import_drizzle.drizzleAdapter)(db, {
245
+ provider: "sqlite",
246
+ schema: {
247
+ ...schema_exports
248
+ }
249
+ }),
250
+ socialProviders: {
251
+ google: {
252
+ enabled: true,
253
+ clientId: process.env.GOOGLE_CLIENT_ID ?? "",
254
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? ""
255
+ }
256
+ },
257
+ ...config
258
+ });
259
+ };
260
+
261
+ // src/client/types.ts
262
+ var DEFAULT_CONFIG = {
263
+ authorizeEndpoint: "/api/auth/oauth2/authorize",
264
+ tokenEndpoint: "/api/auth/oauth2/token",
265
+ userEndpoint: "/api/auth/oauth2/userinfo",
266
+ cookieName: "access_token",
267
+ cookieMaxAge: 60 * 60 * 24 * 7
268
+ // 7 Days
269
+ };
270
+ function resolveConfig(config) {
271
+ return {
272
+ ...DEFAULT_CONFIG,
273
+ ...config
274
+ };
275
+ }
276
+ function buildAuthorizationUrl(config, clientConfig, options) {
277
+ const targetUrl = new URL(config.url + config.authorizeEndpoint);
278
+ const scopes = ["openid", "profile", "email"];
279
+ if (options?.additionalScopes) {
280
+ scopes.push(...options.additionalScopes);
281
+ }
282
+ targetUrl.searchParams.set("response_type", "code");
283
+ targetUrl.searchParams.set("client_id", clientConfig.clientId);
284
+ targetUrl.searchParams.set("redirect_uri", clientConfig.redirectUri);
285
+ targetUrl.searchParams.set("scope", scopes.join(" "));
286
+ if (options?.state) {
287
+ targetUrl.searchParams.set("state", options.state);
288
+ }
289
+ return targetUrl.toString();
290
+ }
291
+ async function exchangeCodeForTokens(config, clientConfig, code) {
292
+ const response = await fetch(config.url + config.tokenEndpoint, {
293
+ method: "POST",
294
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
295
+ body: new URLSearchParams({
296
+ grant_type: "authorization_code",
297
+ client_id: clientConfig.clientId,
298
+ client_secret: clientConfig.clientSecret,
299
+ redirect_uri: clientConfig.redirectUri,
300
+ code
301
+ })
302
+ });
303
+ if (!response.ok) {
304
+ const errorText = await response.text();
305
+ throw new Error(`Token exchange failed (${response.status}): ${errorText}`);
306
+ }
307
+ const tokens = await response.json();
308
+ if (!tokens.access_token) {
309
+ throw new Error("No access token in response");
310
+ }
311
+ return tokens;
312
+ }
313
+ async function fetchUserInfo(config, accessToken) {
314
+ try {
315
+ const response = await fetch(config.url + config.userEndpoint, {
316
+ headers: {
317
+ "Authorization": `Bearer ${accessToken}`
318
+ }
319
+ });
320
+ if (!response.ok) {
321
+ return null;
322
+ }
323
+ return await response.json();
324
+ } catch {
325
+ return null;
326
+ }
327
+ }
328
+
329
+ // src/client/sveltekit.ts
330
+ var import_kit = require("@sveltejs/kit");
331
+ function createSvelteKitClient(centralAuthConfig) {
332
+ const config = resolveConfig(centralAuthConfig);
333
+ return {
334
+ /**
335
+ * Get the current Central Auth configuration.
336
+ */
337
+ getConfig: () => ({ ...config }),
338
+ /**
339
+ * Initiates the OAuth2 sign-in flow by redirecting to the Central Auth Server.
340
+ * Uses SvelteKit's redirect() which throws a redirect response.
341
+ *
342
+ * @param clientConfig - OAuth2 client configuration
343
+ * @param options - Optional sign-in options
344
+ * @throws Redirect to the Central Auth authorization endpoint
345
+ */
346
+ signIn: (clientConfig, options) => {
347
+ const authUrl = buildAuthorizationUrl(config, clientConfig, options);
348
+ (0, import_kit.redirect)(302, authUrl);
349
+ },
350
+ /**
351
+ * Builds the authorization URL without redirecting.
352
+ * Useful when you need to return the URL for client-side navigation.
353
+ *
354
+ * @param clientConfig - OAuth2 client configuration
355
+ * @param options - Optional sign-in options
356
+ * @returns The authorization URL string
357
+ */
358
+ getSignInUrl: (clientConfig, options) => {
359
+ return buildAuthorizationUrl(config, clientConfig, options);
360
+ },
361
+ /**
362
+ * Handles the OAuth2 callback, exchanges the code for tokens, and sets the session cookie.
363
+ * Uses SvelteKit's cookies API for cookie management.
364
+ *
365
+ * @param event - SvelteKit RequestEvent
366
+ * @param clientConfig - OAuth2 client configuration
367
+ * @param options - Optional callback options
368
+ * @throws Redirect on success, throws error on failure
369
+ */
370
+ handleSignInCallback: async (event, clientConfig, options) => {
371
+ const { url, cookies: cookies2 } = event;
372
+ const code = url.searchParams.get("code");
373
+ const error = url.searchParams.get("error");
374
+ const errorDescription = url.searchParams.get("error_description");
375
+ if (error) {
376
+ throw new Error(`Authentication failed: ${errorDescription || error}`);
377
+ }
378
+ if (!code) {
379
+ throw new Error("Missing authorization code");
380
+ }
381
+ try {
382
+ const tokens = await exchangeCodeForTokens(config, clientConfig, code);
383
+ cookies2.set(config.cookieName, tokens.access_token, {
384
+ httpOnly: true,
385
+ secure: event.url.protocol === "https:",
386
+ sameSite: "lax",
387
+ path: "/",
388
+ maxAge: config.cookieMaxAge
389
+ });
390
+ const successPath = options?.successRedirectPath || "/";
391
+ (0, import_kit.redirect)(302, successPath);
392
+ } catch (err) {
393
+ if (err && typeof err === "object" && "status" in err) {
394
+ throw err;
395
+ }
396
+ console.error("Auth callback error:", err);
397
+ throw new Error("Authentication failed");
398
+ }
399
+ },
400
+ /**
401
+ * Signs out the user by clearing the session cookie.
402
+ *
403
+ * @param cookies - SvelteKit Cookies object
404
+ * @param redirectPath - Path to redirect to after sign out (default: "/")
405
+ * @throws Redirect to the specified path
406
+ */
407
+ signOut: (cookies2, redirectPath = "/") => {
408
+ cookies2.delete(config.cookieName, { path: "/" });
409
+ (0, import_kit.redirect)(302, redirectPath);
410
+ },
411
+ /**
412
+ * Clears the session cookie without redirecting.
413
+ * Useful when you need more control over the response.
414
+ *
415
+ * @param cookies - SvelteKit Cookies object
416
+ */
417
+ clearSession: (cookies2) => {
418
+ cookies2.delete(config.cookieName, { path: "/" });
419
+ },
420
+ /**
421
+ * Retrieves the access token from cookies.
422
+ *
423
+ * @param cookies - SvelteKit Cookies object
424
+ * @returns The access token or null if not found
425
+ */
426
+ getAccessToken: (cookies2) => {
427
+ return cookies2.get(config.cookieName) ?? null;
428
+ },
429
+ /**
430
+ * Fetches user information from the Central Auth Server.
431
+ *
432
+ * @param accessToken - The access token to use for authentication
433
+ * @returns The user information or null if the request fails
434
+ */
435
+ getUser: async (accessToken) => {
436
+ return fetchUserInfo(config, accessToken);
437
+ },
438
+ /**
439
+ * Gets the current user session from cookies.
440
+ * Combines getAccessToken and getUser for convenience.
441
+ *
442
+ * @param cookies - SvelteKit Cookies object
443
+ * @returns The user information or null if not authenticated
444
+ */
445
+ getSession: async (cookies2) => {
446
+ const accessToken = cookies2.get(config.cookieName);
447
+ if (!accessToken) return null;
448
+ return fetchUserInfo(config, accessToken);
449
+ },
450
+ /**
451
+ * Checks if the user is authenticated (has access token in cookies).
452
+ * Note: This only checks for token presence, not validity.
453
+ *
454
+ * @param cookies - SvelteKit Cookies object
455
+ * @returns true if an access token is present
456
+ */
457
+ isAuthenticated: (cookies2) => {
458
+ return !!cookies2.get(config.cookieName);
459
+ },
460
+ /**
461
+ * Protects a route by checking authentication and redirecting if needed.
462
+ * Use in +page.server.ts or +layout.server.ts load functions.
463
+ *
464
+ * @param cookies - SvelteKit Cookies object
465
+ * @param loginPath - Path to redirect to for login (default: "/login")
466
+ * @throws Redirect to login path if not authenticated
467
+ */
468
+ requireAuth: (cookies2, loginPath = "/login") => {
469
+ if (!cookies2.get(config.cookieName)) {
470
+ (0, import_kit.redirect)(302, loginPath);
471
+ }
472
+ }
473
+ };
474
+ }
475
+ var svelteClient = createSvelteKitClient;
476
+
477
+ // src/client/nextjs.ts
478
+ var import_headers = require("next/headers");
479
+ var import_navigation = require("next/navigation");
480
+ var import_server = require("next/server");
481
+ function createNextClient(centralAuthConfig) {
482
+ const config = resolveConfig(centralAuthConfig);
483
+ return {
484
+ /**
485
+ * Get the current Central Auth configuration.
486
+ */
487
+ getConfig: () => ({ ...config }),
488
+ /**
489
+ * Initiates the OAuth2 sign-in flow by returning a redirect Response.
490
+ * Use in Route Handlers (App Router).
491
+ *
492
+ * @param clientConfig - OAuth2 client configuration
493
+ * @param options - Optional sign-in options
494
+ * @returns NextResponse redirect to the Central Auth authorization endpoint
495
+ */
496
+ signIn: (clientConfig, options) => {
497
+ const authUrl = buildAuthorizationUrl(config, clientConfig, options);
498
+ return import_server.NextResponse.redirect(authUrl);
499
+ },
500
+ /**
501
+ * Builds the authorization URL without redirecting.
502
+ * Useful for client-side navigation or custom redirect logic.
503
+ *
504
+ * @param clientConfig - OAuth2 client configuration
505
+ * @param options - Optional sign-in options
506
+ * @returns The authorization URL string
507
+ */
508
+ getSignInUrl: (clientConfig, options) => {
509
+ return buildAuthorizationUrl(config, clientConfig, options);
510
+ },
511
+ /**
512
+ * Handles the OAuth2 callback in Route Handlers.
513
+ * Exchanges the code for tokens and sets the session cookie.
514
+ *
515
+ * @param request - NextRequest object
516
+ * @param clientConfig - OAuth2 client configuration
517
+ * @param options - Optional callback options
518
+ * @returns NextResponse with redirect and cookie set
519
+ */
520
+ handleSignInCallback: async (request, clientConfig, options) => {
521
+ const { searchParams } = new URL(request.url);
522
+ const code = searchParams.get("code");
523
+ const error = searchParams.get("error");
524
+ const errorDescription = searchParams.get("error_description");
525
+ if (error) {
526
+ return import_server.NextResponse.json(
527
+ { error: errorDescription || error },
528
+ { status: 400 }
529
+ );
530
+ }
531
+ if (!code) {
532
+ return import_server.NextResponse.json(
533
+ { error: "Missing authorization code" },
534
+ { status: 400 }
535
+ );
536
+ }
537
+ try {
538
+ const tokens = await exchangeCodeForTokens(config, clientConfig, code);
539
+ const successPath = options?.successRedirectPath || "/";
540
+ const successUrl = new URL(successPath, clientConfig.appUrl);
541
+ const response = import_server.NextResponse.redirect(successUrl);
542
+ response.cookies.set(config.cookieName, tokens.access_token, {
543
+ httpOnly: true,
544
+ secure: process.env.NODE_ENV === "production",
545
+ sameSite: "lax",
546
+ path: "/",
547
+ maxAge: config.cookieMaxAge
548
+ });
549
+ return response;
550
+ } catch (err) {
551
+ console.error("Auth callback error:", err);
552
+ return import_server.NextResponse.json(
553
+ { error: "Authentication failed" },
554
+ { status: 500 }
555
+ );
556
+ }
557
+ },
558
+ /**
559
+ * Signs out the user by clearing the session cookie.
560
+ * Use in Route Handlers.
561
+ *
562
+ * @param clientConfig - OAuth2 client configuration
563
+ * @param redirectPath - Path to redirect to after sign out (default: "/")
564
+ * @returns NextResponse with redirect and cookie cleared
565
+ */
566
+ signOut: (clientConfig, redirectPath = "/") => {
567
+ const redirectUrl = new URL(redirectPath, clientConfig.appUrl);
568
+ const response = import_server.NextResponse.redirect(redirectUrl);
569
+ response.cookies.set(config.cookieName, "", {
570
+ httpOnly: true,
571
+ secure: process.env.NODE_ENV === "production",
572
+ sameSite: "lax",
573
+ path: "/",
574
+ maxAge: 0
575
+ });
576
+ return response;
577
+ },
578
+ /**
579
+ * Retrieves the access token from cookies.
580
+ * Use in Server Components or Route Handlers.
581
+ *
582
+ * @returns The access token or null if not found
583
+ */
584
+ getAccessToken: async () => {
585
+ const cookieStore = await (0, import_headers.cookies)();
586
+ return cookieStore.get(config.cookieName)?.value ?? null;
587
+ },
588
+ /**
589
+ * Retrieves the access token from a NextRequest.
590
+ * Use in middleware or Route Handlers when you have the request object.
591
+ *
592
+ * @param request - NextRequest object
593
+ * @returns The access token or null if not found
594
+ */
595
+ getAccessTokenFromRequest: (request) => {
596
+ return request.cookies.get(config.cookieName)?.value ?? null;
597
+ },
598
+ /**
599
+ * Fetches user information from the Central Auth Server.
600
+ *
601
+ * @param accessToken - The access token to use for authentication
602
+ * @returns The user information or null if the request fails
603
+ */
604
+ getUser: async (accessToken) => {
605
+ return fetchUserInfo(config, accessToken);
606
+ },
607
+ /**
608
+ * Gets the current user session.
609
+ * Use in Server Components.
610
+ *
611
+ * @returns The user information or null if not authenticated
612
+ */
613
+ getSession: async () => {
614
+ const cookieStore = await (0, import_headers.cookies)();
615
+ const accessToken = cookieStore.get(config.cookieName)?.value;
616
+ if (!accessToken) return null;
617
+ return fetchUserInfo(config, accessToken);
618
+ },
619
+ /**
620
+ * Gets the current user session from a request.
621
+ * Use in middleware or Route Handlers.
622
+ *
623
+ * @param request - NextRequest object
624
+ * @returns The user information or null if not authenticated
625
+ */
626
+ getSessionFromRequest: async (request) => {
627
+ const accessToken = request.cookies.get(config.cookieName)?.value;
628
+ if (!accessToken) return null;
629
+ return fetchUserInfo(config, accessToken);
630
+ },
631
+ /**
632
+ * Checks if the user is authenticated.
633
+ * Use in Server Components.
634
+ *
635
+ * @returns true if an access token is present
636
+ */
637
+ isAuthenticated: async () => {
638
+ const cookieStore = await (0, import_headers.cookies)();
639
+ return !!cookieStore.get(config.cookieName)?.value;
640
+ },
641
+ /**
642
+ * Checks if the request is authenticated.
643
+ * Use in middleware.
644
+ *
645
+ * @param request - NextRequest object
646
+ * @returns true if an access token is present
647
+ */
648
+ isAuthenticatedRequest: (request) => {
649
+ return !!request.cookies.get(config.cookieName)?.value;
650
+ },
651
+ /**
652
+ * Protects a route by checking authentication and redirecting if needed.
653
+ * Use in Server Components.
654
+ *
655
+ * @param loginPath - Path to redirect to for login (default: "/login")
656
+ * @throws Redirect to login path if not authenticated
657
+ */
658
+ requireAuth: async (loginPath = "/login") => {
659
+ const cookieStore = await (0, import_headers.cookies)();
660
+ if (!cookieStore.get(config.cookieName)?.value) {
661
+ (0, import_navigation.redirect)(loginPath);
662
+ }
663
+ },
664
+ /**
665
+ * Creates a middleware-compatible auth check.
666
+ * Returns a NextResponse redirect if not authenticated.
667
+ *
668
+ * @param request - NextRequest object
669
+ * @param loginPath - Path to redirect to for login (default: "/login")
670
+ * @returns NextResponse redirect if not authenticated, null otherwise
671
+ */
672
+ middlewareAuth: (request, loginPath = "/login") => {
673
+ if (!request.cookies.get(config.cookieName)?.value) {
674
+ const loginUrl = new URL(loginPath, request.url);
675
+ loginUrl.searchParams.set("from", request.nextUrl.pathname);
676
+ return import_server.NextResponse.redirect(loginUrl);
677
+ }
678
+ return null;
679
+ }
680
+ };
681
+ }
682
+ var nextClient = createNextClient;
683
+ // Annotate the CommonJS export names for ESM import in node:
684
+ 0 && (module.exports = {
685
+ DEFAULT_CONFIG,
686
+ account,
687
+ accountRelations,
688
+ createAuth,
689
+ createNextClient,
690
+ createSvelteKitClient,
691
+ nextClient,
692
+ oauthAccessToken,
693
+ oauthAccessTokenRelations,
694
+ oauthApplication,
695
+ oauthApplicationRelations,
696
+ oauthConsent,
697
+ oauthConsentRelations,
698
+ session,
699
+ sessionRelations,
700
+ svelteClient,
701
+ user,
702
+ userRelations,
703
+ verification
704
+ });
705
+ //# sourceMappingURL=index.cjs.map