@coreiam/auth 1.0.392-beta.2 → 1.0.392-beta.3
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/core/index.d.ts +1 -0
- package/dist/core/index.js +27 -4
- package/dist/express/index.js +7 -7
- package/dist/hono/index.d.ts +33 -0
- package/dist/hono/index.js +195 -0
- package/dist/nextjs/middleware.js +11 -3
- package/package.json +15 -4
package/dist/core/index.d.ts
CHANGED
package/dist/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CoreIAM = void 0;
|
|
3
|
+
exports.CSRF_PROTECTED_PATHS = exports.CoreIAM = void 0;
|
|
4
4
|
exports.toIdentity = toIdentity;
|
|
5
5
|
// src/core/index.ts
|
|
6
6
|
const jose_1 = require("jose");
|
|
@@ -104,15 +104,33 @@ class CoreIAM {
|
|
|
104
104
|
return input.get('cookie') || '';
|
|
105
105
|
return input.cookie || '';
|
|
106
106
|
}
|
|
107
|
+
// private readSessionCookie(input: SessionInput): string | null {
|
|
108
|
+
// const raw = this.readCookieHeader(input);
|
|
109
|
+
// if (!raw) return null;
|
|
110
|
+
// // Anchored to a real cookie-name boundary (same pattern proxy() uses),
|
|
111
|
+
// // so a cookie named "notjwt" or "xjwt" can never match.
|
|
112
|
+
// const escaped = this.sessionCookieName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
113
|
+
// const match = raw.match(new RegExp(`(?:^|;\\s*)${escaped}=([^;]+)`));
|
|
114
|
+
// return match ? decodeURIComponent(match[1]) : null;
|
|
115
|
+
// }
|
|
116
|
+
// PATCH 1 — readSessionCookie: a corrupt cookie value (%E0%A4%A) currently
|
|
117
|
+
// throws URIError out of verifySession → 500 on /session. A corrupt value is
|
|
118
|
+
// an invalid token, not a server error: return it raw; jwtVerify classifies
|
|
119
|
+
// it as 'invalid_signature'.
|
|
107
120
|
readSessionCookie(input) {
|
|
108
121
|
const raw = this.readCookieHeader(input);
|
|
109
122
|
if (!raw)
|
|
110
123
|
return null;
|
|
111
|
-
// Anchored to a real cookie-name boundary (same pattern proxy() uses),
|
|
112
|
-
// so a cookie named "notjwt" or "xjwt" can never match.
|
|
113
124
|
const escaped = this.sessionCookieName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
114
125
|
const match = raw.match(new RegExp(`(?:^|;\\s*)${escaped}=([^;]+)`));
|
|
115
|
-
|
|
126
|
+
if (!match)
|
|
127
|
+
return null;
|
|
128
|
+
try {
|
|
129
|
+
return decodeURIComponent(match[1]);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return match[1];
|
|
133
|
+
}
|
|
116
134
|
}
|
|
117
135
|
async verifySession(input) {
|
|
118
136
|
const token = this.readSessionCookie(input);
|
|
@@ -376,3 +394,8 @@ class CoreIAM {
|
|
|
376
394
|
}
|
|
377
395
|
}
|
|
378
396
|
exports.CoreIAM = CoreIAM;
|
|
397
|
+
exports.CSRF_PROTECTED_PATHS = new Set([
|
|
398
|
+
'/auth/login', '/auth/register', '/auth/discover-tenants',
|
|
399
|
+
'/auth/request-otp', '/auth/verify-otp', '/auth/mfa/login',
|
|
400
|
+
'/auth/profile', '/auth/mfa/setup', '/auth/mfa/verify', '/auth/mfa/disable',
|
|
401
|
+
]);
|
package/dist/express/index.js
CHANGED
|
@@ -6,11 +6,6 @@ exports.requireAuth = requireAuth;
|
|
|
6
6
|
// src/express/index.ts
|
|
7
7
|
const express_1 = require("express");
|
|
8
8
|
const core_1 = require("../core");
|
|
9
|
-
const CSRF_PROTECTED = new Set([
|
|
10
|
-
'/auth/login', '/auth/register', '/auth/profile',
|
|
11
|
-
'/auth/mfa/setup', '/auth/mfa/verify', '/auth/mfa/disable',
|
|
12
|
-
'/auth/request-otp', '/auth/verify-otp',
|
|
13
|
-
]);
|
|
14
9
|
/** Express 4 does not catch async rejections — route them to next(err). */
|
|
15
10
|
const wrap = (fn) => (req, res, next) => { fn(req, res, next).catch(next); };
|
|
16
11
|
function sessionCookie(name, value, maxAgeSec, isProd) {
|
|
@@ -70,7 +65,12 @@ function coreIamExpress(options) {
|
|
|
70
65
|
const code = req.query.code;
|
|
71
66
|
const state = req.query.state;
|
|
72
67
|
const redirectUri = `${appUrl}${authPath}/callback/${provider}`;
|
|
73
|
-
const target = `/auth/oauth/callback/${provider}?code=${code}&state=${state}&redirectUri=${encodeURIComponent(redirectUri)}`;
|
|
68
|
+
// const target = `/auth/oauth/callback/${provider}?code=${code}&state=${state}&redirectUri=${encodeURIComponent(redirectUri)}`;
|
|
69
|
+
// OAuth callback — encode all three params:
|
|
70
|
+
const target = `/auth/oauth/callback/${provider}`
|
|
71
|
+
+ `?code=${encodeURIComponent(String(code ?? ''))}`
|
|
72
|
+
+ `&state=${encodeURIComponent(String(state ?? ''))}`
|
|
73
|
+
+ `&redirectUri=${encodeURIComponent(redirectUri)}`;
|
|
74
74
|
const response = await iam.proxy(target, { method: 'GET' }, toHeaders(req));
|
|
75
75
|
const data = await response.json().catch(() => ({}));
|
|
76
76
|
// Account linking: redirect to CoreIAM's hosted confirmation page
|
|
@@ -138,7 +138,7 @@ function coreIamExpress(options) {
|
|
|
138
138
|
init.body = req.body ? JSON.stringify(req.body) : undefined;
|
|
139
139
|
init.headers = { 'Content-Type': 'application/json' };
|
|
140
140
|
}
|
|
141
|
-
const response =
|
|
141
|
+
const response = core_1.CSRF_PROTECTED_PATHS.has(target)
|
|
142
142
|
? await iam.proxyWithCsrfProtection(target, init, toHeaders(req))
|
|
143
143
|
: await iam.proxy(target, init, toHeaders(req));
|
|
144
144
|
const data = await response.json().catch(() => ({}));
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Hono, type MiddlewareHandler } from 'hono';
|
|
2
|
+
import { CoreIAMIdentity } from '../core';
|
|
3
|
+
export interface CoreIamHonoOptions {
|
|
4
|
+
apiKey: string;
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
/** Your app's public URL (OAuth callbacks redirect back here). */
|
|
7
|
+
appUrl: string;
|
|
8
|
+
/** Mount path of the adapter. MUST match how you mount it. Default '/api/auth'. */
|
|
9
|
+
authPath?: string;
|
|
10
|
+
signInUrl?: string;
|
|
11
|
+
successUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Pass to your app: `new Hono<CoreIAMEnv>()` so `c.get('identity')` is typed. */
|
|
14
|
+
export type CoreIAMEnv = {
|
|
15
|
+
Variables: {
|
|
16
|
+
identity: CoreIAMIdentity;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Drop-in auth router for Hono (Node, Bun, Deno, Workers).
|
|
21
|
+
* const app = new Hono();
|
|
22
|
+
* app.route('/api/auth', coreIamHono({ apiKey, baseUrl, appUrl }));
|
|
23
|
+
* Same behavior as the Express adapter: CSRF handshake, OAuth + account
|
|
24
|
+
* linking, cookie forwarding, silent refresh on /session.
|
|
25
|
+
*/
|
|
26
|
+
export declare function coreIamHono(options: CoreIamHonoOptions): Hono;
|
|
27
|
+
export interface RequireAuthConfig {
|
|
28
|
+
apiKey?: string;
|
|
29
|
+
baseUrl?: string;
|
|
30
|
+
signInUrl?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Route guard: local verify → c.get('identity'); 401s API requests, redirects pages. */
|
|
33
|
+
export declare function requireAuth(config?: RequireAuthConfig): MiddlewareHandler<CoreIAMEnv>;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.coreIamHono = coreIamHono;
|
|
4
|
+
exports.requireAuth = requireAuth;
|
|
5
|
+
// src/hono/index.ts
|
|
6
|
+
const hono_1 = require("hono");
|
|
7
|
+
const core_1 = require("../core");
|
|
8
|
+
/**
|
|
9
|
+
* Drop-in auth router for Hono (Node, Bun, Deno, Workers).
|
|
10
|
+
* const app = new Hono();
|
|
11
|
+
* app.route('/api/auth', coreIamHono({ apiKey, baseUrl, appUrl }));
|
|
12
|
+
* Same behavior as the Express adapter: CSRF handshake, OAuth + account
|
|
13
|
+
* linking, cookie forwarding, silent refresh on /session.
|
|
14
|
+
*/
|
|
15
|
+
function coreIamHono(options) {
|
|
16
|
+
const appUrl = options.appUrl.replace(/\/+$/, '');
|
|
17
|
+
const authPath = (options.authPath ?? '/api/auth').replace(/\/+$/, '');
|
|
18
|
+
const successUrl = options.successUrl ?? '/';
|
|
19
|
+
const signInUrl = options.signInUrl ?? '/login';
|
|
20
|
+
const gatewayUrl = options.baseUrl.replace(/\/+$/, '');
|
|
21
|
+
const isProd = process.env.NODE_ENV === 'production';
|
|
22
|
+
const iam = new core_1.CoreIAM(options);
|
|
23
|
+
const app = new hono_1.Hono();
|
|
24
|
+
// c.req.path is always the FULL path (Hono does not rewrite it per sub-app),
|
|
25
|
+
// so the mount prefix must be stripped by hand to get '/login' → '/auth/login'.
|
|
26
|
+
const relPath = (c) => {
|
|
27
|
+
const p = c.req.path;
|
|
28
|
+
if (p === authPath)
|
|
29
|
+
return '/';
|
|
30
|
+
if (p.startsWith(`${authPath}/`))
|
|
31
|
+
return p.slice(authPath.length);
|
|
32
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
33
|
+
console.warn(`[coreIamHono] ${p} does not start with authPath '${authPath}' — ` +
|
|
34
|
+
`if you mounted the adapter elsewhere, pass the same value as authPath.`);
|
|
35
|
+
}
|
|
36
|
+
return p;
|
|
37
|
+
};
|
|
38
|
+
// Same attributes as the Express adapter's sessionCookie().
|
|
39
|
+
const sessionCookie = (name, value, maxAgeSec) => `${name}=${encodeURIComponent(value)}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${maxAgeSec}${isProd ? '; Secure' : ''}`;
|
|
40
|
+
// Mirrors the Express adapter (json() + urlencoded()): both content types
|
|
41
|
+
// accepted on every auth route, re-serialized as JSON for the gateway.
|
|
42
|
+
const readBody = async (c) => {
|
|
43
|
+
if ((c.req.header('content-type') || '').includes('application/x-www-form-urlencoded')) {
|
|
44
|
+
return Object.fromEntries(new URLSearchParams(await c.req.text()).entries());
|
|
45
|
+
}
|
|
46
|
+
return c.req.json().catch(() => undefined);
|
|
47
|
+
};
|
|
48
|
+
// ── CORS preflight short-circuit — same as the Next.js middleware, so ──
|
|
49
|
+
// cross-origin frontends work with zero setup. Same-origin (the documented
|
|
50
|
+
// pattern) never sends OPTIONS.
|
|
51
|
+
app.options('*', (c) => {
|
|
52
|
+
const origin = c.req.header('origin');
|
|
53
|
+
if (origin) {
|
|
54
|
+
c.header('Access-Control-Allow-Origin', origin);
|
|
55
|
+
c.header('Access-Control-Allow-Credentials', 'true');
|
|
56
|
+
c.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
57
|
+
c.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-CSRF-Token');
|
|
58
|
+
c.header('Vary', 'Origin', { append: true });
|
|
59
|
+
}
|
|
60
|
+
return c.body(null, 204);
|
|
61
|
+
});
|
|
62
|
+
// ── GET {authPath}/session — local verify + silent refresh (React provider) ──
|
|
63
|
+
app.get('/session', async (c) => {
|
|
64
|
+
const result = await iam.verifySession(c.req.raw.headers);
|
|
65
|
+
if (result.identity)
|
|
66
|
+
return c.json(result.identity);
|
|
67
|
+
if (result.reason === 'expired') {
|
|
68
|
+
const { identity, setCookies } = await iam.refreshSession(c.req.raw.headers);
|
|
69
|
+
if (identity) {
|
|
70
|
+
setCookies?.forEach((sc) => c.header('Set-Cookie', sc, { append: true }));
|
|
71
|
+
return c.json(identity);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return c.json({ error: 'unauthenticated' }, 401);
|
|
75
|
+
});
|
|
76
|
+
// ── GET {authPath}/oauth/:provider — initiate ──
|
|
77
|
+
app.get('/oauth/:provider', async (c, next) => {
|
|
78
|
+
const provider = c.req.param('provider');
|
|
79
|
+
if (provider === 'link')
|
|
80
|
+
return next(); // link/confirm is POSTed below
|
|
81
|
+
const redirectUri = `${appUrl}${authPath}/callback/${provider}`;
|
|
82
|
+
const target = `/auth/oauth/initiate/${provider}?redirectUri=${encodeURIComponent(redirectUri)}&scopes=email,profile`;
|
|
83
|
+
const response = await iam.proxy(target, { method: 'GET' }, c.req.raw.headers);
|
|
84
|
+
const data = await response.json().catch(() => ({}));
|
|
85
|
+
if (data.url)
|
|
86
|
+
return c.redirect(data.url, 302);
|
|
87
|
+
return c.redirect(signInUrl, 302);
|
|
88
|
+
});
|
|
89
|
+
// ── GET {authPath}/callback/:provider ──
|
|
90
|
+
app.get('/callback/:provider', async (c) => {
|
|
91
|
+
const provider = c.req.param('provider');
|
|
92
|
+
const code = c.req.query('code');
|
|
93
|
+
const state = c.req.query('state');
|
|
94
|
+
const redirectUri = `${appUrl}${authPath}/callback/${provider}`;
|
|
95
|
+
const target = `/auth/oauth/callback/${provider}`
|
|
96
|
+
+ `?code=${encodeURIComponent(code ?? '')}`
|
|
97
|
+
+ `&state=${encodeURIComponent(state ?? '')}`
|
|
98
|
+
+ `&redirectUri=${encodeURIComponent(redirectUri)}`;
|
|
99
|
+
const response = await iam.proxy(target, { method: 'GET' }, c.req.raw.headers);
|
|
100
|
+
const data = (await response.json().catch(() => ({})));
|
|
101
|
+
// Account linking → CoreIAM's hosted confirmation page
|
|
102
|
+
if (data.action === 'link_candidate') {
|
|
103
|
+
const redirect = new URL(`${gatewayUrl}/auth/hosted/confirm-link`);
|
|
104
|
+
redirect.searchParams.set('token', data.tempToken);
|
|
105
|
+
redirect.searchParams.set('provider', data.provider);
|
|
106
|
+
redirect.searchParams.set('email', data.email || '');
|
|
107
|
+
redirect.searchParams.set('appOrigin', appUrl);
|
|
108
|
+
return c.redirect(redirect.toString(), 303);
|
|
109
|
+
}
|
|
110
|
+
// Normal login: forward gateway cookies, then redirect.
|
|
111
|
+
response.headers.getSetCookie().forEach((sc) => c.header('Set-Cookie', sc, { append: true }));
|
|
112
|
+
return c.redirect(successUrl, 302);
|
|
113
|
+
});
|
|
114
|
+
// ── POST {authPath}/oauth/link/confirm (hosted page posts urlencoded) ──
|
|
115
|
+
app.post('/oauth/link/confirm', async (c) => {
|
|
116
|
+
const contentType = c.req.header('content-type') || '';
|
|
117
|
+
let formData;
|
|
118
|
+
if (contentType.includes('application/x-www-form-urlencoded')) {
|
|
119
|
+
const params = new URLSearchParams(await c.req.text());
|
|
120
|
+
formData = { tempToken: params.get('tempToken') ?? undefined, password: params.get('password') ?? undefined };
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
formData = (await c.req.json().catch(() => ({})));
|
|
124
|
+
}
|
|
125
|
+
const response = await iam.proxy('/auth/oauth/link/confirm', {
|
|
126
|
+
method: 'POST',
|
|
127
|
+
body: JSON.stringify(formData),
|
|
128
|
+
headers: { 'Content-Type': 'application/json' },
|
|
129
|
+
}, c.req.raw.headers);
|
|
130
|
+
const data = (await response.json().catch(() => ({})));
|
|
131
|
+
if (response.ok && data.success) {
|
|
132
|
+
const finalUrl = new URL(data.redirectUri || '/', appUrl).toString();
|
|
133
|
+
if (data.accessToken)
|
|
134
|
+
c.header('Set-Cookie', sessionCookie('jwt', data.accessToken, 24 * 60 * 60), { append: true });
|
|
135
|
+
if (data.clientRefreshToken)
|
|
136
|
+
c.header('Set-Cookie', sessionCookie('refreshToken', data.clientRefreshToken, 7 * 24 * 60 * 60), { append: true });
|
|
137
|
+
// 200 + JS redirect — NOT a 303: breaks the cross-site redirect chain so
|
|
138
|
+
// the browser sends the freshly-set SameSite=Lax cookies on the next hop.
|
|
139
|
+
// (Identical to the Express adapter and Next middleware — do not "simplify".)
|
|
140
|
+
return c.html(`<!DOCTYPE html>
|
|
141
|
+
<html>
|
|
142
|
+
<head><title>Linking Successful</title></head>
|
|
143
|
+
<body>
|
|
144
|
+
<p>Account linked successfully! Redirecting...</p>
|
|
145
|
+
<script>window.location.href = ${JSON.stringify(finalUrl)};</script>
|
|
146
|
+
</body>
|
|
147
|
+
</html>`);
|
|
148
|
+
}
|
|
149
|
+
const errorRedirect = new URL(`${gatewayUrl}/auth/hosted/confirm-link`);
|
|
150
|
+
errorRedirect.searchParams.set('token', formData.tempToken || '');
|
|
151
|
+
errorRedirect.searchParams.set('provider', data.provider || 'google');
|
|
152
|
+
errorRedirect.searchParams.set('email', data.email || '');
|
|
153
|
+
errorRedirect.searchParams.set('appOrigin', appUrl);
|
|
154
|
+
errorRedirect.searchParams.set('error', data.message || 'Invalid password. Link failed.');
|
|
155
|
+
return c.redirect(errorRedirect.toString(), 303);
|
|
156
|
+
});
|
|
157
|
+
// ── Everything else: generic JSON passthrough (login, register, logout,
|
|
158
|
+
// csrf-token, MFA, OTP, profile). CSRF-protected endpoints run the
|
|
159
|
+
// handshake first — the same set, from core, as Express/Next. ──
|
|
160
|
+
app.all('*', async (c) => {
|
|
161
|
+
const target = `/auth${relPath(c)}`;
|
|
162
|
+
const init = { method: c.req.method };
|
|
163
|
+
if (c.req.method !== 'GET' && c.req.method !== 'HEAD') {
|
|
164
|
+
const body = await readBody(c);
|
|
165
|
+
if (body !== undefined) {
|
|
166
|
+
init.body = JSON.stringify(body);
|
|
167
|
+
init.headers = { 'Content-Type': 'application/json' };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const response = core_1.CSRF_PROTECTED_PATHS.has(target)
|
|
171
|
+
? await iam.proxyWithCsrfProtection(target, init, c.req.raw.headers)
|
|
172
|
+
: await iam.proxy(target, init, c.req.raw.headers);
|
|
173
|
+
c.status(response.status);
|
|
174
|
+
response.headers.getSetCookie().forEach((sc) => c.header('Set-Cookie', sc, { append: true }));
|
|
175
|
+
return c.json(await response.json().catch(() => ({})));
|
|
176
|
+
});
|
|
177
|
+
return app;
|
|
178
|
+
}
|
|
179
|
+
/** Route guard: local verify → c.get('identity'); 401s API requests, redirects pages. */
|
|
180
|
+
function requireAuth(config = {}) {
|
|
181
|
+
const iam = new core_1.CoreIAM(config);
|
|
182
|
+
const { signInUrl = '/login' } = config;
|
|
183
|
+
return async (c, next) => {
|
|
184
|
+
const identity = await iam.getSession(c.req.raw.headers);
|
|
185
|
+
if (!identity) {
|
|
186
|
+
const accept = c.req.header('accept') || '';
|
|
187
|
+
const wantsJson = c.req.path.startsWith('/api') || accept.includes('json') || accept.trim() === '*/*';
|
|
188
|
+
if (wantsJson)
|
|
189
|
+
return c.json({ error: 'unauthenticated' }, 401);
|
|
190
|
+
return c.redirect(signInUrl, 302);
|
|
191
|
+
}
|
|
192
|
+
c.set('identity', identity);
|
|
193
|
+
await next();
|
|
194
|
+
};
|
|
195
|
+
}
|
|
@@ -275,13 +275,21 @@ async function coreIamAuth(request) {
|
|
|
275
275
|
const code = searchParams.get('code');
|
|
276
276
|
const state = searchParams.get('state');
|
|
277
277
|
const redirectUri = `${process.env.NEXT_PUBLIC_APP_URL}/api/auth/callback/${provider}`;
|
|
278
|
-
targetPath = `/auth/oauth/callback/${provider}?code=${code}&state=${state}&redirectUri=${redirectUri}`;
|
|
278
|
+
// targetPath = `/auth/oauth/callback/${provider}?code=${code}&state=${state}&redirectUri=${redirectUri}`;
|
|
279
|
+
// OAuth callback targetPath — encode all three:
|
|
280
|
+
targetPath = `/auth/oauth/callback/${provider}`
|
|
281
|
+
+ `?code=${encodeURIComponent(code ?? '')}`
|
|
282
|
+
+ `&state=${encodeURIComponent(state ?? '')}`
|
|
283
|
+
+ `&redirectUri=${encodeURIComponent(redirectUri)}`;
|
|
279
284
|
}
|
|
280
|
-
const
|
|
285
|
+
const init = {
|
|
281
286
|
method,
|
|
282
287
|
body: body ? JSON.stringify(body) : undefined,
|
|
283
288
|
headers: { 'Content-Type': 'application/json' },
|
|
284
|
-
}
|
|
289
|
+
};
|
|
290
|
+
const response = core_1.CSRF_PROTECTED_PATHS.has(targetPath)
|
|
291
|
+
? await iam.proxyWithCsrfProtection(targetPath, init, request.headers)
|
|
292
|
+
: await iam.proxy(targetPath, init, request.headers);
|
|
285
293
|
// Handle OAuth Initiate Redirects
|
|
286
294
|
if (pathname.startsWith('/api/auth/oauth/') && !pathname.includes('callback') && !pathname.includes('link')) {
|
|
287
295
|
const data = await response.json().catch(() => ({}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreiam/auth",
|
|
3
|
-
"version": "1.0.392-beta.
|
|
3
|
+
"version": "1.0.392-beta.3",
|
|
4
4
|
"main": "./dist/core/index.js",
|
|
5
5
|
"types": "./dist/core/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -37,17 +37,24 @@
|
|
|
37
37
|
"auth",
|
|
38
38
|
"saas",
|
|
39
39
|
"multi-tenant",
|
|
40
|
-
"nextjs"
|
|
40
|
+
"nextjs",
|
|
41
|
+
"hono",
|
|
42
|
+
"react",
|
|
43
|
+
"vite",
|
|
44
|
+
"express"
|
|
41
45
|
],
|
|
42
46
|
"author": "coreIAM",
|
|
43
47
|
"license": "MIT",
|
|
44
48
|
"publishConfig": {
|
|
45
49
|
"access": "public"
|
|
46
50
|
},
|
|
51
|
+
"./hono": { "types": "./dist/hono/index.d.ts", "import": "./dist/hono/index.js", "require": "./dist/hono/index.js" },
|
|
52
|
+
"./ui": { "types": "./dist/ui/buttons.d.ts", "import": "./dist/ui/buttons.js", "require": "./dist/ui/buttons.js" },
|
|
47
53
|
"peerDependencies": {
|
|
48
54
|
"express": "^4.0.0 || ^5.0.0",
|
|
49
55
|
"next": ">=14",
|
|
50
|
-
"react": ">=18"
|
|
56
|
+
"react": ">=18",
|
|
57
|
+
"hono": ">=4"
|
|
51
58
|
},
|
|
52
59
|
"peerDependenciesMeta": {
|
|
53
60
|
"next": {
|
|
@@ -58,6 +65,9 @@
|
|
|
58
65
|
},
|
|
59
66
|
"express": {
|
|
60
67
|
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"hono": {
|
|
70
|
+
"optional": true
|
|
61
71
|
}
|
|
62
72
|
},
|
|
63
73
|
"devDependencies": {
|
|
@@ -69,7 +79,8 @@
|
|
|
69
79
|
"react": "^19.2.7",
|
|
70
80
|
"supertest": "^7.3.0",
|
|
71
81
|
"typescript": "^5.0.0",
|
|
72
|
-
"vitest": "^3.2.7"
|
|
82
|
+
"vitest": "^3.2.7",
|
|
83
|
+
"hono": "^4.6.0"
|
|
73
84
|
},
|
|
74
85
|
"dependencies": {
|
|
75
86
|
"@radix-ui/react-slot": "^1.3.3",
|