oauth.do 0.1.15 → 0.2.1

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/hono.js ADDED
@@ -0,0 +1,599 @@
1
+ import { getCookie, deleteCookie, setCookie } from 'hono/cookie';
2
+ import * as jose from 'jose';
3
+ import { Hono } from 'hono';
4
+
5
+ // src/hono.ts
6
+
7
+ // src/session.ts
8
+ var defaultSessionConfig = {
9
+ cookieName: "session",
10
+ cookieMaxAge: 60 * 60 * 24 * 7,
11
+ // 7 days
12
+ cookieSecure: true,
13
+ cookieSameSite: "lax",
14
+ secret: "oauth-do-dev-secret-change-in-production"
15
+ };
16
+ var ALGORITHM = "AES-GCM";
17
+ var IV_LENGTH = 12;
18
+ var TAG_LENGTH = 128;
19
+ async function getEncryptionKey(secret) {
20
+ const encoder = new TextEncoder();
21
+ return crypto.subtle.importKey(
22
+ "raw",
23
+ encoder.encode(secret.padEnd(32, "0").slice(0, 32)),
24
+ { name: ALGORITHM },
25
+ false,
26
+ ["encrypt", "decrypt"]
27
+ );
28
+ }
29
+ async function encodeSession(session, secret) {
30
+ const key = await getEncryptionKey(secret ?? defaultSessionConfig.secret);
31
+ const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH));
32
+ const encoder = new TextEncoder();
33
+ const data = encoder.encode(JSON.stringify(session));
34
+ const ciphertext = await crypto.subtle.encrypt(
35
+ { name: ALGORITHM, iv, tagLength: TAG_LENGTH },
36
+ key,
37
+ data
38
+ );
39
+ const combined2 = new Uint8Array(iv.length + ciphertext.byteLength);
40
+ combined2.set(iv, 0);
41
+ combined2.set(new Uint8Array(ciphertext), iv.length);
42
+ return btoa(String.fromCharCode(...combined2));
43
+ }
44
+ async function decodeSession(encoded, secret) {
45
+ try {
46
+ const key = await getEncryptionKey(secret ?? defaultSessionConfig.secret);
47
+ const combined2 = Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0));
48
+ const iv = combined2.slice(0, IV_LENGTH);
49
+ const ciphertext = combined2.slice(IV_LENGTH);
50
+ const decrypted = await crypto.subtle.decrypt(
51
+ { name: ALGORITHM, iv, tagLength: TAG_LENGTH },
52
+ key,
53
+ ciphertext
54
+ );
55
+ const decoder = new TextDecoder();
56
+ const parsed = JSON.parse(decoder.decode(decrypted));
57
+ if (!isValidSessionData(parsed)) {
58
+ return null;
59
+ }
60
+ return parsed;
61
+ } catch {
62
+ return null;
63
+ }
64
+ }
65
+ function isValidSessionData(data) {
66
+ if (data === null || typeof data !== "object") {
67
+ return false;
68
+ }
69
+ const session = data;
70
+ if (typeof session.userId !== "string" || session.userId.length === 0) {
71
+ return false;
72
+ }
73
+ if (typeof session.accessToken !== "string" || session.accessToken.length === 0) {
74
+ return false;
75
+ }
76
+ if (session.organizationId !== void 0 && typeof session.organizationId !== "string") {
77
+ return false;
78
+ }
79
+ if (session.email !== void 0 && typeof session.email !== "string") {
80
+ return false;
81
+ }
82
+ if (session.name !== void 0 && typeof session.name !== "string") {
83
+ return false;
84
+ }
85
+ if (session.refreshToken !== void 0 && typeof session.refreshToken !== "string") {
86
+ return false;
87
+ }
88
+ if (session.expiresAt !== void 0 && typeof session.expiresAt !== "number") {
89
+ return false;
90
+ }
91
+ return true;
92
+ }
93
+ function getSessionConfig(env) {
94
+ const validSameSite = ["strict", "lax", "none"];
95
+ let cookieSameSite = defaultSessionConfig.cookieSameSite;
96
+ if (env?.SESSION_COOKIE_SAME_SITE) {
97
+ const value = env.SESSION_COOKIE_SAME_SITE;
98
+ if (validSameSite.includes(value)) {
99
+ cookieSameSite = value;
100
+ }
101
+ }
102
+ let cookieMaxAge = defaultSessionConfig.cookieMaxAge;
103
+ if (env?.SESSION_COOKIE_MAX_AGE) {
104
+ const parsed = parseInt(env.SESSION_COOKIE_MAX_AGE, 10);
105
+ if (!Number.isNaN(parsed) && parsed > 0) {
106
+ cookieMaxAge = parsed;
107
+ }
108
+ }
109
+ return {
110
+ secret: env?.SESSION_SECRET ?? defaultSessionConfig.secret,
111
+ cookieName: env?.SESSION_COOKIE_NAME ?? defaultSessionConfig.cookieName,
112
+ cookieMaxAge,
113
+ cookieSecure: env?.SESSION_COOKIE_SECURE !== "false",
114
+ cookieSameSite
115
+ };
116
+ }
117
+
118
+ // src/session-hono.ts
119
+ async function setSessionCookie(c, session, config = defaultSessionConfig) {
120
+ const encoded = await encodeSession(session, config.secret);
121
+ setCookie(c, config.cookieName, encoded, {
122
+ path: "/",
123
+ httpOnly: true,
124
+ secure: config.cookieSecure,
125
+ sameSite: config.cookieSameSite === "none" ? "None" : config.cookieSameSite === "strict" ? "Strict" : "Lax",
126
+ maxAge: config.cookieMaxAge
127
+ });
128
+ }
129
+ function clearSessionCookie(c, config = defaultSessionConfig) {
130
+ deleteCookie(c, config.cookieName, { path: "/" });
131
+ }
132
+ async function getSessionFromCookie(c, config = defaultSessionConfig) {
133
+ const encoded = getCookie(c, config.cookieName);
134
+ if (!encoded) return null;
135
+ return decodeSession(encoded, config.secret);
136
+ }
137
+ function sessionAuth(options = {}) {
138
+ return async (c, next) => {
139
+ const env = c.env ?? {};
140
+ const config = { ...getSessionConfig(env), ...options.config };
141
+ const session = await getSessionFromCookie(c, config);
142
+ c.set("session", session);
143
+ c.set("sessionUser", session ? {
144
+ id: session.userId,
145
+ email: session.email,
146
+ name: session.name,
147
+ organizationId: session.organizationId
148
+ } : null);
149
+ await next();
150
+ };
151
+ }
152
+ function requireSession(options = {}) {
153
+ return async (c, next) => {
154
+ const env = c.env ?? {};
155
+ const config = { ...getSessionConfig(env), ...options.config };
156
+ const session = await getSessionFromCookie(c, config);
157
+ if (!session) {
158
+ return c.json({ error: "Unauthorized", message: "Authentication required" }, 401);
159
+ }
160
+ if (session.expiresAt && Date.now() >= session.expiresAt) {
161
+ clearSessionCookie(c, config);
162
+ return c.json({ error: "Unauthorized", message: "Session expired" }, 401);
163
+ }
164
+ c.set("session", session);
165
+ c.set("sessionUser", {
166
+ id: session.userId,
167
+ email: session.email,
168
+ name: session.name,
169
+ organizationId: session.organizationId
170
+ });
171
+ await next();
172
+ };
173
+ }
174
+ function createWorkOSClient(apiKey2) {
175
+ const baseUrl = "https://api.workos.com";
176
+ return {
177
+ getAuthorizationUrl(options) {
178
+ const params = new URLSearchParams({
179
+ client_id: options.clientId,
180
+ redirect_uri: options.redirectUri,
181
+ response_type: "code",
182
+ ...options.state && { state: options.state },
183
+ ...options.provider && { provider: options.provider }
184
+ });
185
+ return `https://api.workos.com/sso/authorize?${params.toString()}`;
186
+ },
187
+ async authenticateWithCode(options) {
188
+ const response = await fetch(`${baseUrl}/user_management/authenticate`, {
189
+ method: "POST",
190
+ headers: {
191
+ "Content-Type": "application/x-www-form-urlencoded",
192
+ "Authorization": `Bearer ${apiKey2}`
193
+ },
194
+ body: new URLSearchParams({
195
+ grant_type: "authorization_code",
196
+ client_id: options.clientId,
197
+ code: options.code,
198
+ redirect_uri: options.redirectUri
199
+ }).toString()
200
+ });
201
+ if (!response.ok) {
202
+ const error = await response.text();
203
+ throw new Error(`WorkOS authentication failed: ${response.status} - ${error}`);
204
+ }
205
+ return response.json();
206
+ },
207
+ async refreshToken(options) {
208
+ const response = await fetch(`${baseUrl}/user_management/authenticate`, {
209
+ method: "POST",
210
+ headers: {
211
+ "Content-Type": "application/x-www-form-urlencoded",
212
+ "Authorization": `Bearer ${apiKey2}`
213
+ },
214
+ body: new URLSearchParams({
215
+ grant_type: "refresh_token",
216
+ client_id: options.clientId,
217
+ refresh_token: options.refreshToken
218
+ }).toString()
219
+ });
220
+ if (!response.ok) {
221
+ const error = await response.text();
222
+ throw new Error(`Token refresh failed: ${response.status} - ${error}`);
223
+ }
224
+ return response.json();
225
+ }
226
+ };
227
+ }
228
+ function createOAuthRoutes(options = {}) {
229
+ const app = new Hono();
230
+ app.use("*", async (c, next) => {
231
+ await next();
232
+ const contentType = c.res.headers.get("content-type");
233
+ if (contentType?.includes("application/json") && !contentType.includes("charset")) {
234
+ c.res.headers.set("content-type", "application/json; charset=utf-8");
235
+ }
236
+ });
237
+ app.get("/login", (c) => {
238
+ const env = c.env ?? {};
239
+ const apiKey2 = options.workosApiKey ?? env.WORKOS_API_KEY;
240
+ const clientId = options.clientId ?? env.WORKOS_CLIENT_ID;
241
+ if (!apiKey2) {
242
+ return c.json({ error: "Server configuration error", message: "WORKOS_API_KEY not configured" }, 500);
243
+ }
244
+ if (!clientId) {
245
+ return c.json({ error: "Server configuration error", message: "WORKOS_CLIENT_ID not configured" }, 500);
246
+ }
247
+ const workos = createWorkOSClient(apiKey2);
248
+ const url = new URL(c.req.url);
249
+ const baseUrl = options.redirectBaseUrl ?? env.AUTH_REDIRECT_BASE_URL ?? `${url.protocol}//${url.host}`;
250
+ const intendedRedirect = c.req.query("redirect_uri") || "/";
251
+ const provider = c.req.query("provider");
252
+ const state = btoa(JSON.stringify({ redirect: intendedRedirect }));
253
+ const authUrl = workos.getAuthorizationUrl({
254
+ clientId,
255
+ redirectUri: `${baseUrl}/auth/callback`,
256
+ state,
257
+ provider
258
+ });
259
+ return c.redirect(authUrl);
260
+ });
261
+ app.get("/callback", async (c) => {
262
+ const env = c.env ?? {};
263
+ const apiKey2 = options.workosApiKey ?? env.WORKOS_API_KEY;
264
+ const clientId = options.clientId ?? env.WORKOS_CLIENT_ID;
265
+ const sessionConfig = { ...getSessionConfig(env), ...options.session };
266
+ const debug = options.debug ?? env.DEBUG === "true";
267
+ if (!apiKey2) {
268
+ return c.json({ error: "Server configuration error", message: "WORKOS_API_KEY not configured" }, 500);
269
+ }
270
+ if (!clientId) {
271
+ return c.json({ error: "Server configuration error", message: "WORKOS_CLIENT_ID not configured" }, 500);
272
+ }
273
+ const code = c.req.query("code");
274
+ const state = c.req.query("state");
275
+ const error = c.req.query("error");
276
+ const errorDescription = c.req.query("error_description");
277
+ if (error) {
278
+ if (debug) console.error("[Auth] OAuth error:", error, errorDescription);
279
+ return c.json({ error: "Authentication failed", message: errorDescription || error }, 400);
280
+ }
281
+ if (!code) {
282
+ return c.json({ error: "Missing authorization code" }, 400);
283
+ }
284
+ const workos = createWorkOSClient(apiKey2);
285
+ const url = new URL(c.req.url);
286
+ const baseUrl = options.redirectBaseUrl ?? env.AUTH_REDIRECT_BASE_URL ?? `${url.protocol}//${url.host}`;
287
+ try {
288
+ const result = await workos.authenticateWithCode({
289
+ clientId,
290
+ code,
291
+ redirectUri: `${baseUrl}/auth/callback`
292
+ });
293
+ const session = {
294
+ userId: result.user.id,
295
+ organizationId: result.user.organization_id,
296
+ email: result.user.email,
297
+ name: [result.user.first_name, result.user.last_name].filter(Boolean).join(" ") || void 0,
298
+ accessToken: result.access_token,
299
+ refreshToken: result.refresh_token,
300
+ expiresAt: result.expires_in ? Date.now() + result.expires_in * 1e3 : void 0
301
+ };
302
+ await setSessionCookie(c, session, sessionConfig);
303
+ await options.onLogin?.(session, c);
304
+ let redirectTo = "/";
305
+ if (state) {
306
+ try {
307
+ const stateData = JSON.parse(atob(state));
308
+ redirectTo = stateData.redirect || "/";
309
+ } catch {
310
+ }
311
+ }
312
+ if (!redirectTo.startsWith("/")) {
313
+ redirectTo = "/";
314
+ }
315
+ return c.redirect(redirectTo);
316
+ } catch (err) {
317
+ if (debug) console.error("[Auth] OAuth callback error:", err);
318
+ return c.json({
319
+ error: "Authentication failed",
320
+ message: err instanceof Error ? err.message : "Unknown error"
321
+ }, 500);
322
+ }
323
+ });
324
+ app.get("/logout", async (c) => {
325
+ const env = c.env ?? {};
326
+ const sessionConfig = { ...getSessionConfig(env), ...options.session };
327
+ clearSessionCookie(c, sessionConfig);
328
+ await options.onLogout?.(c);
329
+ const redirectTo = c.req.query("redirect_uri") || "/";
330
+ if (!redirectTo.startsWith("/")) {
331
+ return c.redirect("/");
332
+ }
333
+ return c.redirect(redirectTo);
334
+ });
335
+ app.post("/logout", async (c) => {
336
+ const env = c.env ?? {};
337
+ const sessionConfig = { ...getSessionConfig(env), ...options.session };
338
+ clearSessionCookie(c, sessionConfig);
339
+ await options.onLogout?.(c);
340
+ return c.json({ success: true, message: "Logged out successfully" });
341
+ });
342
+ app.get("/me", async (c) => {
343
+ const env = c.env ?? {};
344
+ const sessionConfig = { ...getSessionConfig(env), ...options.session };
345
+ const session = await getSessionFromCookie(c, sessionConfig);
346
+ if (!session) {
347
+ return c.json({ error: "Unauthorized", message: "Not authenticated" }, 401);
348
+ }
349
+ if (session.expiresAt && Date.now() >= session.expiresAt) {
350
+ clearSessionCookie(c, sessionConfig);
351
+ return c.json({ error: "Unauthorized", message: "Session expired" }, 401);
352
+ }
353
+ return c.json({
354
+ id: session.userId,
355
+ email: session.email,
356
+ name: session.name,
357
+ organizationId: session.organizationId
358
+ });
359
+ });
360
+ app.post("/refresh", async (c) => {
361
+ const env = c.env ?? {};
362
+ const apiKey2 = options.workosApiKey ?? env.WORKOS_API_KEY;
363
+ const clientId = options.clientId ?? env.WORKOS_CLIENT_ID;
364
+ const sessionConfig = { ...getSessionConfig(env), ...options.session };
365
+ const debug = options.debug ?? env.DEBUG === "true";
366
+ if (!apiKey2) {
367
+ return c.json({ error: "Server configuration error", message: "WORKOS_API_KEY not configured" }, 500);
368
+ }
369
+ if (!clientId) {
370
+ return c.json({ error: "Server configuration error", message: "WORKOS_CLIENT_ID not configured" }, 500);
371
+ }
372
+ const session = await getSessionFromCookie(c, sessionConfig);
373
+ if (!session) {
374
+ return c.json({ error: "Unauthorized", message: "Not authenticated" }, 401);
375
+ }
376
+ if (!session.refreshToken) {
377
+ return c.json({ error: "Cannot refresh", message: "No refresh token available" }, 400);
378
+ }
379
+ const workos = createWorkOSClient(apiKey2);
380
+ try {
381
+ const result = await workos.refreshToken({
382
+ clientId,
383
+ refreshToken: session.refreshToken
384
+ });
385
+ const updatedSession = {
386
+ ...session,
387
+ accessToken: result.access_token,
388
+ refreshToken: result.refresh_token || session.refreshToken,
389
+ expiresAt: result.expires_in ? Date.now() + result.expires_in * 1e3 : void 0
390
+ };
391
+ await setSessionCookie(c, updatedSession, sessionConfig);
392
+ return c.json({ success: true, expiresAt: updatedSession.expiresAt });
393
+ } catch (err) {
394
+ if (debug) console.error("[Auth] Token refresh error:", err);
395
+ clearSessionCookie(c, sessionConfig);
396
+ return c.json({
397
+ error: "Refresh failed",
398
+ message: err instanceof Error ? err.message : "Unknown error"
399
+ }, 401);
400
+ }
401
+ });
402
+ return app;
403
+ }
404
+
405
+ // src/hono.ts
406
+ var OAUTH_DO_CONFIG = {
407
+ clientId: "client_01JQYTRXK9ZPD8JPJTKDCRB656",
408
+ jwksUri: "https://api.workos.com/sso/jwks/client_01JQYTRXK9ZPD8JPJTKDCRB656"
409
+ };
410
+ var TOKEN_CACHE_TTL = 5 * 60;
411
+ var CACHE_URL_PREFIX = "https://oauth.do/_cache/token/";
412
+ async function hashToken(token) {
413
+ const data = new TextEncoder().encode(token);
414
+ const hashBuffer = await crypto.subtle.digest("SHA-256", data);
415
+ return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
416
+ }
417
+ async function getCachedUser(token) {
418
+ try {
419
+ const cache = caches.default;
420
+ const hash = await hashToken(token);
421
+ const cacheKey = new Request(`${CACHE_URL_PREFIX}${hash}`);
422
+ const cached = await cache.match(cacheKey);
423
+ if (!cached) return null;
424
+ const data = await cached.json();
425
+ if (data.expiresAt < Date.now()) return null;
426
+ return data.user;
427
+ } catch {
428
+ return null;
429
+ }
430
+ }
431
+ async function cacheUser(token, user) {
432
+ try {
433
+ const cache = caches.default;
434
+ const hash = await hashToken(token);
435
+ const cacheKey = new Request(`${CACHE_URL_PREFIX}${hash}`);
436
+ const data = { user, expiresAt: Date.now() + TOKEN_CACHE_TTL * 1e3 };
437
+ const response = new Response(JSON.stringify(data), {
438
+ headers: { "Cache-Control": `max-age=${TOKEN_CACHE_TTL}` }
439
+ });
440
+ await cache.put(cacheKey, response);
441
+ } catch {
442
+ }
443
+ }
444
+ function extractToken(c, cookieName, headerName) {
445
+ const authHeader = c.req.header(headerName);
446
+ if (authHeader?.startsWith("Bearer ")) {
447
+ return authHeader.slice(7);
448
+ }
449
+ const cookie = getCookie(c, cookieName);
450
+ if (cookie) return cookie;
451
+ return null;
452
+ }
453
+ function payloadToUser(payload) {
454
+ return {
455
+ id: payload.sub || "",
456
+ email: payload.email,
457
+ name: payload.name,
458
+ organizationId: payload.org_id,
459
+ roles: payload.roles,
460
+ permissions: payload.permissions,
461
+ metadata: payload.metadata
462
+ };
463
+ }
464
+ var jwksCache = null;
465
+ var jwksCacheExpiry = 0;
466
+ async function getJwks(jwksUri, cacheTtl) {
467
+ const now = Date.now();
468
+ if (jwksCache && jwksCacheExpiry > now) {
469
+ return jwksCache;
470
+ }
471
+ jwksCache = jose.createRemoteJWKSet(new URL(jwksUri));
472
+ jwksCacheExpiry = now + cacheTtl * 1e3;
473
+ return jwksCache;
474
+ }
475
+ function auth(options = {}) {
476
+ const {
477
+ cookieName = "auth",
478
+ headerName = "Authorization",
479
+ clientId = OAUTH_DO_CONFIG.clientId,
480
+ jwksUri = OAUTH_DO_CONFIG.jwksUri,
481
+ skip,
482
+ jwksCacheTtl = 3600
483
+ } = options;
484
+ return async (c, next) => {
485
+ c.set("user", null);
486
+ c.set("userId", null);
487
+ c.set("isAuth", false);
488
+ c.set("token", null);
489
+ if (skip?.(c)) {
490
+ return next();
491
+ }
492
+ const token = extractToken(c, cookieName, headerName);
493
+ if (!token) {
494
+ return next();
495
+ }
496
+ c.set("token", token);
497
+ const cached = await getCachedUser(token);
498
+ if (cached) {
499
+ c.set("user", cached);
500
+ c.set("userId", cached.id);
501
+ c.set("isAuth", true);
502
+ return next();
503
+ }
504
+ try {
505
+ const jwks = await getJwks(jwksUri, jwksCacheTtl);
506
+ const { payload } = await jose.jwtVerify(token, jwks, {
507
+ audience: clientId
508
+ });
509
+ const user = payloadToUser(payload);
510
+ c.set("user", user);
511
+ c.set("userId", user.id);
512
+ c.set("isAuth", true);
513
+ await cacheUser(token, user);
514
+ } catch {
515
+ }
516
+ return next();
517
+ };
518
+ }
519
+ function requireAuth(options = {}) {
520
+ const { redirectTo, roles, permissions, ...authOptions } = options;
521
+ return async (c, next) => {
522
+ if (c.var.user === void 0) {
523
+ await auth(authOptions)(c, async () => {
524
+ });
525
+ }
526
+ if (!c.var.isAuth || !c.var.user) {
527
+ if (redirectTo) {
528
+ return c.redirect(redirectTo);
529
+ }
530
+ return c.json({ error: "Authentication required" }, 401);
531
+ }
532
+ if (roles?.length) {
533
+ const userRoles = c.var.user.roles || [];
534
+ const hasRole = roles.some((r) => userRoles.includes(r));
535
+ if (!hasRole) {
536
+ return c.json({ error: "Insufficient permissions" }, 403);
537
+ }
538
+ }
539
+ if (permissions?.length) {
540
+ const userPerms = c.var.user.permissions || [];
541
+ const hasAllPerms = permissions.every((p) => userPerms.includes(p));
542
+ if (!hasAllPerms) {
543
+ return c.json({ error: "Insufficient permissions" }, 403);
544
+ }
545
+ }
546
+ return next();
547
+ };
548
+ }
549
+ function apiKey(options) {
550
+ const { headerName = "X-API-Key", verify } = options;
551
+ return async (c, next) => {
552
+ c.set("user", null);
553
+ c.set("userId", null);
554
+ c.set("isAuth", false);
555
+ c.set("token", null);
556
+ const key = c.req.header(headerName);
557
+ if (!key) {
558
+ return c.json({ error: "API key required" }, 401);
559
+ }
560
+ const user = await verify(key, c);
561
+ if (!user) {
562
+ return c.json({ error: "Invalid API key" }, 401);
563
+ }
564
+ c.set("user", user);
565
+ c.set("userId", user.id);
566
+ c.set("isAuth", true);
567
+ c.set("token", key);
568
+ return next();
569
+ };
570
+ }
571
+ function combined(options) {
572
+ return async (c, next) => {
573
+ if (options.auth) {
574
+ await auth(options.auth)(c, async () => {
575
+ });
576
+ if (c.var.isAuth) {
577
+ return next();
578
+ }
579
+ }
580
+ if (options.apiKey) {
581
+ const key = c.req.header(options.apiKey.headerName || "X-API-Key");
582
+ if (key) {
583
+ const user = await options.apiKey.verify(key, c);
584
+ if (user) {
585
+ c.set("user", user);
586
+ c.set("userId", user.id);
587
+ c.set("isAuth", true);
588
+ c.set("token", key);
589
+ return next();
590
+ }
591
+ }
592
+ }
593
+ return c.json({ error: "Authentication required" }, 401);
594
+ };
595
+ }
596
+
597
+ export { apiKey, auth, combined, createOAuthRoutes, decodeSession, encodeSession, getSessionConfig, requireAuth, requireSession, sessionAuth };
598
+ //# sourceMappingURL=hono.js.map
599
+ //# sourceMappingURL=hono.js.map