@henosia/app-next 1.0.2 → 1.0.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/README.md CHANGED
@@ -120,7 +120,19 @@ import {
120
120
  } from '@henosia/app-next'
121
121
  ```
122
122
 
123
- `verifyHenosiaAuthToken(request)` MUST be called from any protected page/route handler/server action — the
123
+ ## Server-side auth guards
124
+
125
+ Methods to add authorization guards around pages, router handlers, and server actions.
126
+
127
+ ```ts
128
+ import {
129
+ requireHenosiaAuth,
130
+ routeWithHenosiaAuth,
131
+ getHenosiaAuth
132
+ } from '@henosia/app-next/auth/server-guards'
133
+ ```
134
+
135
+ `requireHenosiaAuth` or `routeWithHenosiaAuth` MUST be called from any protected page/route handler/server action — the
124
136
  middleware only performs a fast pre-check.
125
137
 
126
138
  ## App-switcher hook
@@ -159,15 +171,16 @@ export function MyAppSwitcher() {
159
171
 
160
172
  ## Subpath exports
161
173
 
162
- | Subpath | Purpose |
163
- |------------------------------------------------|------------------------------------------------------------|
164
- | `@henosia/app-next` | Server-side helpers (`auth`, `verifyHenosiaAuthToken`, …) |
165
- | `@henosia/app-next/shared` | Shared constants & types (no runtime deps) |
166
- | `@henosia/app-next/auth/middleware` | `createHenosiaAuthMiddleware` |
167
- | `@henosia/app-next/auth/server` | Lower-level server-side auth surface (re-exported by root) |
168
- | `@henosia/app-next/auth/client` | Better-auth `authClient` for React |
169
- | `@henosia/app-next/api/auth` | `GET`, `POST` for `/api/auth/[...all]` |
170
- | `@henosia/app-next/api/platform` | `GET` for `/api/henosia-platform/[...all]` |
171
- | `@henosia/app-next/platform/app-switcher` | `useAppSwitcher` React hook |
172
- | `@henosia/app-next/supabase/server` | Server-side Supabase client factory |
173
- | `@henosia/app-next/supabase/client` | Browser Supabase client factory |
174
+ | Subpath | Purpose |
175
+ |-------------------------------------------|----------------------------------------------------------------------------|
176
+ | `@henosia/app-next` | Server-side helpers (`auth`, `verifyHenosiaAuthToken`, …) |
177
+ | `@henosia/app-next/shared` | Shared constants & types (no runtime deps) |
178
+ | `@henosia/app-next/auth/middleware` | `createHenosiaAuthMiddleware` |
179
+ | `@henosia/app-next/auth/server` | Lower-level server-side auth surface (re-exported by root) |
180
+ | `@henosia/app-next/auth/server-guards` | Page and route auth guards (`requireHenosiaAuth`, `routeWithHenosiaAuth`, ...) |
181
+ | `@henosia/app-next/auth/client` | Better-auth `authClient` for React |
182
+ | `@henosia/app-next/api/auth` | `GET`, `POST` for `/api/auth/[...all]` |
183
+ | `@henosia/app-next/api/platform` | `GET` for `/api/henosia-platform/[...all]` |
184
+ | `@henosia/app-next/platform/app-switcher` | `useAppSwitcher` React hook |
185
+ | `@henosia/app-next/supabase/server` | Server-side Supabase client factory |
186
+ | `@henosia/app-next/supabase/client` | Browser Supabase client factory |
@@ -1,5 +1,6 @@
1
1
  /*! Copyright (c) 2026 Henosia ApS. Licensed under the Henosia Commercial Source License v1.0. See LICENSE */
2
2
  import { henosiaAuthConfig, isUnauthorizedException, verifyHenosiaAuthToken } from "../auth/server.mjs";
3
+ import { applySecurityHeaders } from "../auth/server-guards.mjs";
3
4
  //#region src/api/platform/v1/app-switcher.ts
4
5
  /**
5
6
  * Handler for the Henosia Platform `app-switcher` endpoint.
@@ -15,10 +16,10 @@ async function handleAppSwitcher(request) {
15
16
  redirect: "error",
16
17
  headers: { authorization: `Bearer ${accessTokenResponse.idToken}` }
17
18
  });
18
- return Response.json(await response.json(), {
19
+ return applySecurityHeaders(Response.json(await response.json(), {
19
20
  status: response.status,
20
21
  statusText: response.statusText
21
- });
22
+ }));
22
23
  } catch (e) {
23
24
  if (isUnauthorizedException(e)) return Response.json({ error: "Your session is invalid or expired. Please reload the page to sign in again." }, { status: 401 });
24
25
  console.error("[Henosia Platform] App Switcher API error", e);
@@ -25,6 +25,7 @@ function delayWithCancel(delayMs) {
25
25
  }
26
26
  //#endregion
27
27
  //#region src/auth/middleware.ts
28
+ const INVALID_SESSION_BODY = { error: "Your session is invalid or expired. Please reload the page to sign in again." };
28
29
  /**
29
30
  * Creates a Next.js middleware function that performs the Henosia Auth pre-check.
30
31
  *
@@ -67,14 +68,17 @@ function createHenosiaAuthMiddleware(options = {}) {
67
68
  transferBetterAuthCookiesToNext(request, response);
68
69
  } catch (e) {
69
70
  if (!isUnauthorizedException(e)) {
70
- console.error("[Middleware]", e);
71
+ console.error("[Henosia Auth] Middleware error", e);
71
72
  throw e;
72
73
  }
73
74
  }
74
75
  return response;
75
76
  }
76
77
  if (unauthenticatedPathNames.has(pathname) || !!unauthenticatedPathNamePrefixes.find((p) => pathname.startsWith(p))) return response;
77
- if (!getSessionCookie(request, { cookiePrefix })) return NextResponse.redirect(new URL(HENOSIA_AUTH_SIGN_IN_PATH_NAME, request.url));
78
+ if (!getSessionCookie(request, { cookiePrefix })) {
79
+ if (request.method !== "GET") return NextResponse.json(INVALID_SESSION_BODY, { status: 401 });
80
+ return NextResponse.redirect(new URL(HENOSIA_AUTH_SIGN_IN_PATH_NAME, request.url));
81
+ }
78
82
  try {
79
83
  const { accessTokenResponse, payload, transferBetterAuthCookiesToNext } = await verifyHenosiaAuthToken(request);
80
84
  transferBetterAuthCookiesToNext(request, response);
@@ -84,12 +88,12 @@ function createHenosiaAuthMiddleware(options = {}) {
84
88
  if (process.env.NEXT_PUBLIC_SUPABASE_URL) await exchangeHenosiaTokenForSupabaseSession(request, response, accessTokenResponse.idToken);
85
89
  } catch (e) {
86
90
  if (isUnauthorizedException(e)) {
87
- if (!isPageRequest(request)) return NextResponse.json({ error: "Your session is invalid or expired. Please reload the page to sign in again." }, { status: e.statusCode ?? 401 });
91
+ if (!isPageRequest(request)) return NextResponse.json(INVALID_SESSION_BODY, { status: e.statusCode ?? 401 });
88
92
  const redirectResponse = NextResponse.redirect(new URL(HENOSIA_AUTH_SIGN_IN_PATH_NAME, request.url));
89
93
  removeCachedAccountData(redirectResponse);
90
94
  return redirectResponse;
91
95
  } else {
92
- console.error("[Middleware]", e);
96
+ console.error("[Henosia Auth] Middleware error", e);
93
97
  throw e;
94
98
  }
95
99
  }
@@ -0,0 +1,116 @@
1
+
2
+ import { HenosiaAuthTokenClaims } from "./server.mjs";
3
+ import { NextRequest, NextResponse } from "next/server.js";
4
+
5
+ //#region src/auth/server-guards.d.ts
6
+ /**
7
+ * For Server Components, layouts, and Server Actions.
8
+ *
9
+ * Verifies the current user's Henosia Auth token and returns the verified
10
+ * claims. On unauthorized, redirects to the Henosia sign-in page (the canonical
11
+ * page-level UX); other errors propagate so Next.js' error boundaries / 500
12
+ * page take over.
13
+ *
14
+ * Wrapped in `React.cache` so multiple components in the same render share a
15
+ * single verification.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * // app/dashboard/page.tsx
20
+ * import { requireHenosiaAuth } from '@/lib/henosia-auth'
21
+ *
22
+ * export default async function Page() {
23
+ * const claims = await requireHenosiaAuth()
24
+ * return <Dashboard org={claims['https://henosia.com/organization']} />
25
+ * }
26
+ * ```
27
+ */
28
+ declare const requireHenosiaAuth: () => Promise<HenosiaAuthTokenClaims>;
29
+ /**
30
+ * Non-redirecting variant of {@link requireHenosiaAuth} for layouts and
31
+ * conditional UI (e.g., navbars that need to render either a "Sign in" button
32
+ * or a user menu). Returns `null` when the user is not authenticated; other
33
+ * errors propagate.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * // app/layout.tsx
38
+ * import { getHenosiaAuth } from '@/lib/henosia-auth'
39
+ *
40
+ * export default async function RootLayout({ children }) {
41
+ * const claims = await getHenosiaAuth()
42
+ * return <Shell user={claims?.['https://henosia.com/organization']}>{children}</Shell>
43
+ * }
44
+ * ```
45
+ */
46
+ declare const getHenosiaAuth: () => Promise<HenosiaAuthTokenClaims | null>;
47
+ /**
48
+ * Context object passed to a `routeWithHenosiaAuth` handler
49
+ */
50
+ interface HenosiaAuthContext {
51
+ /** Verified Henosia Auth JWT claims (project, organization, preview flag). */
52
+ payload: HenosiaAuthTokenClaims;
53
+ /**
54
+ * OAuth 2.0 access token, e.g. for forwarding to a downstream API as a
55
+ * `Authorization: Bearer …` header.
56
+ *
57
+ * **Security:** this is a bearer credential. Do **not** log it, echo it back
58
+ * in a response body, embed it in error messages, or persist it. Forward
59
+ * over TLS to trusted downstream services only. Treat it like a password.
60
+ */
61
+ accessToken: string;
62
+ }
63
+ /**
64
+ * A JSON-serializable value that the wrapper will auto-wrap with `NextResponse.json`.
65
+ */
66
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
67
+ [key: string]: JsonValue | undefined;
68
+ };
69
+ /**
70
+ * Allowed return types from a `routeWithHenosiaAuth` handler:
71
+ * - A `Response` (returned verbatim — caller controls status/headers/body).
72
+ * - A JSON-serializable value (auto-wrapped via `NextResponse.json`).
73
+ * - `void` / `undefined` → translated to a `204 No Content` response.
74
+ */
75
+ type HandlerReturn = Response | JsonValue | void;
76
+ type RouteParams<TParams> = TParams | Promise<TParams>;
77
+ type Handler<TParams> = (request: NextRequest, ctx: HenosiaAuthContext & {
78
+ params: TParams;
79
+ }) => HandlerReturn | Promise<HandlerReturn>;
80
+ declare function applySecurityHeaders(response: Response): Response;
81
+ declare function unauthorizedResponse(): NextResponse;
82
+ /**
83
+ * For Next.js Route Handlers (`app/api/**\/route.ts`).
84
+ *
85
+ * Wraps a handler so that:
86
+ * - The request is verified up front.
87
+ * - On success, the handler receives `{ payload, accessToken, params }` and
88
+ * may return either a `Response`, any JSON-serializable value
89
+ * (auto-wrapped via `NextResponse.json`), or `undefined` (→ `204
90
+ * No Content`).
91
+ * - On unauthorized, returns a canonical HTTP `401 Unauthorized` response
92
+ * (RFC 7235): never a redirect.
93
+ * - On any other error (verifying the token *or* thrown by the handler),
94
+ * it's logged with the request's pathname for traceability and a generic
95
+ * `500 Internal Server Error` JSON response is returned (no stack /
96
+ * internal details leaked) — the same OAuth-shaped contract regardless of
97
+ * where the failure originated.
98
+ *
99
+ * Preserves the standard Next.js `(request, { params })` signature, including
100
+ * Next 15's promise-typed `params`.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * // app/api/me/route.ts
105
+ * import { routeWithHenosiaAuth } from '@/lib/henosia-auth'
106
+ *
107
+ * export const GET = routeWithHenosiaAuth((_req, { payload }) => ({
108
+ * organization: payload['https://henosia.com/organization'],
109
+ * }))
110
+ * ```
111
+ */
112
+ declare function routeWithHenosiaAuth<TParams = Record<string, string | string[] | undefined>>(handler: Handler<TParams>): (request: NextRequest, routeCtx: {
113
+ params: RouteParams<TParams>;
114
+ }) => Promise<Response>;
115
+ //#endregion
116
+ export { HenosiaAuthContext, applySecurityHeaders, getHenosiaAuth, requireHenosiaAuth, routeWithHenosiaAuth, unauthorizedResponse };
@@ -0,0 +1,167 @@
1
+ /*! Copyright (c) 2026 Henosia ApS. Licensed under the Henosia Commercial Source License v1.0. See LICENSE */
2
+ import { HENOSIA_AUTH_SIGN_IN_PATH_NAME } from "../shared.mjs";
3
+ import { isUnauthorizedException, verifyHenosiaAuthToken } from "./server.mjs";
4
+ import { headers } from "next/headers.js";
5
+ import { cache } from "react";
6
+ import { redirect } from "next/navigation.js";
7
+ import { NextResponse } from "next/server.js";
8
+ //#region src/auth/server-guards.ts
9
+ async function buildRequestFromHeaders() {
10
+ const h = await headers();
11
+ const url = `${h.get("x-forwarded-proto") ?? "http"}://${h.get("x-forwarded-host") ?? h.get("host") ?? "localhost"}/`;
12
+ return new Request(url, { headers: h });
13
+ }
14
+ async function verifyClaims() {
15
+ const { payload } = await verifyHenosiaAuthToken(await buildRequestFromHeaders());
16
+ return payload;
17
+ }
18
+ /**
19
+ * For Server Components, layouts, and Server Actions.
20
+ *
21
+ * Verifies the current user's Henosia Auth token and returns the verified
22
+ * claims. On unauthorized, redirects to the Henosia sign-in page (the canonical
23
+ * page-level UX); other errors propagate so Next.js' error boundaries / 500
24
+ * page take over.
25
+ *
26
+ * Wrapped in `React.cache` so multiple components in the same render share a
27
+ * single verification.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * // app/dashboard/page.tsx
32
+ * import { requireHenosiaAuth } from '@/lib/henosia-auth'
33
+ *
34
+ * export default async function Page() {
35
+ * const claims = await requireHenosiaAuth()
36
+ * return <Dashboard org={claims['https://henosia.com/organization']} />
37
+ * }
38
+ * ```
39
+ */
40
+ const requireHenosiaAuth = cache(async () => {
41
+ try {
42
+ return await verifyClaims();
43
+ } catch (error) {
44
+ if (isUnauthorizedException(error)) redirect(HENOSIA_AUTH_SIGN_IN_PATH_NAME);
45
+ throw error;
46
+ }
47
+ });
48
+ /**
49
+ * Non-redirecting variant of {@link requireHenosiaAuth} for layouts and
50
+ * conditional UI (e.g., navbars that need to render either a "Sign in" button
51
+ * or a user menu). Returns `null` when the user is not authenticated; other
52
+ * errors propagate.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * // app/layout.tsx
57
+ * import { getHenosiaAuth } from '@/lib/henosia-auth'
58
+ *
59
+ * export default async function RootLayout({ children }) {
60
+ * const claims = await getHenosiaAuth()
61
+ * return <Shell user={claims?.['https://henosia.com/organization']}>{children}</Shell>
62
+ * }
63
+ * ```
64
+ */
65
+ const getHenosiaAuth = cache(async () => {
66
+ try {
67
+ return await verifyClaims();
68
+ } catch (error) {
69
+ if (isUnauthorizedException(error)) return null;
70
+ throw error;
71
+ }
72
+ });
73
+ /**
74
+ * Headers we attach to *every* response produced by `routeWithHenosiaAuth`
75
+ * (success, 401, 500). Auth-protected JSON is per-user and must not be cached
76
+ * by shared caches (RFC 9111 §5.2.2.7 — `private`) and must not be reused
77
+ * even by the user's own cache (`no-store`). `Vary: Cookie` is the formally
78
+ * correct signal that the response varies on the auth cookie (RFC 9110 §12.5.5).
79
+ */
80
+ const SECURITY_HEADERS = {
81
+ "Cache-Control": "private, no-store",
82
+ "Vary": "Cookie"
83
+ };
84
+ function applySecurityHeaders(response) {
85
+ for (const [name, value] of Object.entries(SECURITY_HEADERS)) if (!response.headers.has(name)) response.headers.set(name, value);
86
+ return response;
87
+ }
88
+ function unauthorizedResponse() {
89
+ return NextResponse.json({
90
+ error: "invalid_token",
91
+ error_description: "The access token is missing, invalid, or expired."
92
+ }, {
93
+ status: 401,
94
+ headers: SECURITY_HEADERS
95
+ });
96
+ }
97
+ function internalServerErrorResponse() {
98
+ return NextResponse.json({ error: "internal_server_error" }, {
99
+ status: 500,
100
+ headers: SECURITY_HEADERS
101
+ });
102
+ }
103
+ /**
104
+ * For Next.js Route Handlers (`app/api/**\/route.ts`).
105
+ *
106
+ * Wraps a handler so that:
107
+ * - The request is verified up front.
108
+ * - On success, the handler receives `{ payload, accessToken, params }` and
109
+ * may return either a `Response`, any JSON-serializable value
110
+ * (auto-wrapped via `NextResponse.json`), or `undefined` (→ `204
111
+ * No Content`).
112
+ * - On unauthorized, returns a canonical HTTP `401 Unauthorized` response
113
+ * (RFC 7235): never a redirect.
114
+ * - On any other error (verifying the token *or* thrown by the handler),
115
+ * it's logged with the request's pathname for traceability and a generic
116
+ * `500 Internal Server Error` JSON response is returned (no stack /
117
+ * internal details leaked) — the same OAuth-shaped contract regardless of
118
+ * where the failure originated.
119
+ *
120
+ * Preserves the standard Next.js `(request, { params })` signature, including
121
+ * Next 15's promise-typed `params`.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * // app/api/me/route.ts
126
+ * import { routeWithHenosiaAuth } from '@/lib/henosia-auth'
127
+ *
128
+ * export const GET = routeWithHenosiaAuth((_req, { payload }) => ({
129
+ * organization: payload['https://henosia.com/organization'],
130
+ * }))
131
+ * ```
132
+ */
133
+ function routeWithHenosiaAuth(handler) {
134
+ return async function protectedHandler(request, routeCtx) {
135
+ let payload;
136
+ let accessToken;
137
+ try {
138
+ const verified = await verifyHenosiaAuthToken(request);
139
+ payload = verified.payload;
140
+ accessToken = verified.accessTokenResponse.accessToken;
141
+ } catch (error) {
142
+ if (isUnauthorizedException(error)) return unauthorizedResponse();
143
+ console.error(`[Henosia Auth] Unexpected error verifying token for ${request.method} ${request.nextUrl.pathname}`, error);
144
+ return internalServerErrorResponse();
145
+ }
146
+ let result;
147
+ try {
148
+ const params = await routeCtx.params;
149
+ result = await handler(request, {
150
+ payload,
151
+ accessToken,
152
+ params
153
+ });
154
+ } catch (error) {
155
+ console.error(`[Henosia Auth] Unhandled error in handler for ${request.method} ${request.nextUrl.pathname}`, error);
156
+ return internalServerErrorResponse();
157
+ }
158
+ if (result instanceof Response) return applySecurityHeaders(result);
159
+ if (result === void 0) return new Response(null, {
160
+ status: 204,
161
+ headers: SECURITY_HEADERS
162
+ });
163
+ return NextResponse.json(result, { headers: SECURITY_HEADERS });
164
+ };
165
+ }
166
+ //#endregion
167
+ export { applySecurityHeaders, getHenosiaAuth, requireHenosiaAuth, routeWithHenosiaAuth, unauthorizedResponse };
@@ -1,5 +1,5 @@
1
1
 
2
- import { HenosiaOrganizationContext } from "../shared.mjs";
2
+ import { i as HenosiaOrganizationContext } from "../shared-BWt7Sysv.mjs";
3
3
  import { Auth } from "better-auth";
4
4
  import { NextRequest, NextResponse } from "next/server.js";
5
5
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
 
2
- import { HENOSIA_AUTH_GET_SESSION_PATH_NAME, HENOSIA_AUTH_SIGN_IN_PATH_NAME, HENOSIA_ORGANIZATION_CTX_COOKIE, HenosiaOrganizationContext } from "./shared.mjs";
2
+ import { i as HenosiaOrganizationContext, n as HENOSIA_AUTH_SIGN_IN_PATH_NAME, r as HENOSIA_ORGANIZATION_CTX_COOKIE, t as HENOSIA_AUTH_GET_SESSION_PATH_NAME } from "./shared-BWt7Sysv.mjs";
3
3
  import { HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAMES, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAME_PREFIXES, HenosiaAuthConfig, HenosiaAuthTokenClaims, auth, cookiePrefix, henosiaAuthConfig, isPageOrRefreshTokenRequest, isPageRequest, isUnauthorizedException, verifyHenosiaAuthToken } from "./auth/server.mjs";
4
- export { HENOSIA_AUTH_GET_SESSION_PATH_NAME, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAMES, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAME_PREFIXES, HENOSIA_AUTH_SIGN_IN_PATH_NAME, HENOSIA_ORGANIZATION_CTX_COOKIE, type HenosiaAuthConfig, type HenosiaAuthTokenClaims, type HenosiaOrganizationContext, auth, cookiePrefix, henosiaAuthConfig, isPageOrRefreshTokenRequest, isPageRequest, isUnauthorizedException, verifyHenosiaAuthToken };
4
+ import { HenosiaAuthContext, getHenosiaAuth, requireHenosiaAuth, routeWithHenosiaAuth } from "./auth/server-guards.mjs";
5
+ export { HENOSIA_AUTH_GET_SESSION_PATH_NAME, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAMES, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAME_PREFIXES, HENOSIA_AUTH_SIGN_IN_PATH_NAME, HENOSIA_ORGANIZATION_CTX_COOKIE, type HenosiaAuthConfig, type HenosiaAuthContext, type HenosiaAuthTokenClaims, type HenosiaOrganizationContext, auth, cookiePrefix, getHenosiaAuth, henosiaAuthConfig, isPageOrRefreshTokenRequest, isPageRequest, isUnauthorizedException, requireHenosiaAuth, routeWithHenosiaAuth, verifyHenosiaAuthToken };
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  /*! Copyright (c) 2026 Henosia ApS. Licensed under the Henosia Commercial Source License v1.0. See LICENSE */
2
2
  import { HENOSIA_AUTH_GET_SESSION_PATH_NAME, HENOSIA_AUTH_SIGN_IN_PATH_NAME, HENOSIA_ORGANIZATION_CTX_COOKIE } from "./shared.mjs";
3
3
  import { HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAMES, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAME_PREFIXES, auth, cookiePrefix, henosiaAuthConfig, isPageOrRefreshTokenRequest, isPageRequest, isUnauthorizedException, verifyHenosiaAuthToken } from "./auth/server.mjs";
4
- export { HENOSIA_AUTH_GET_SESSION_PATH_NAME, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAMES, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAME_PREFIXES, HENOSIA_AUTH_SIGN_IN_PATH_NAME, HENOSIA_ORGANIZATION_CTX_COOKIE, auth, cookiePrefix, henosiaAuthConfig, isPageOrRefreshTokenRequest, isPageRequest, isUnauthorizedException, verifyHenosiaAuthToken };
4
+ import { getHenosiaAuth, requireHenosiaAuth, routeWithHenosiaAuth } from "./auth/server-guards.mjs";
5
+ export { HENOSIA_AUTH_GET_SESSION_PATH_NAME, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAMES, HENOSIA_AUTH_MIDDLEWARE_UNAUTHENTICATED_PATH_NAME_PREFIXES, HENOSIA_AUTH_SIGN_IN_PATH_NAME, HENOSIA_ORGANIZATION_CTX_COOKIE, auth, cookiePrefix, getHenosiaAuth, henosiaAuthConfig, isPageOrRefreshTokenRequest, isPageRequest, isUnauthorizedException, requireHenosiaAuth, routeWithHenosiaAuth, verifyHenosiaAuthToken };
@@ -1,5 +1,5 @@
1
1
 
2
- import { HenosiaOrganizationContext } from "../shared.mjs";
2
+ import { i as HenosiaOrganizationContext } from "../shared-BWt7Sysv.mjs";
3
3
 
4
4
  //#region src/platform/app-switcher.d.ts
5
5
  /**
@@ -0,0 +1,19 @@
1
+
2
+ //#region src/shared.d.ts
3
+ declare const HENOSIA_AUTH_SIGN_IN_PATH_NAME = "/sign-in";
4
+ /**
5
+ * The pathname for better-auth's `/get-session` endpoint, used by the React `useSession` hook.
6
+ *
7
+ * `useSession` automatically refetches this endpoint on browser tab focus (and optionally on a polling
8
+ * interval), which we leverage as a built-in keep-alive for the OIDC access/refresh tokens — see
9
+ * `isPageOrRefreshTokenRequest` and the middleware special-case for this path.
10
+ */
11
+ declare const HENOSIA_AUTH_GET_SESSION_PATH_NAME = "/api/auth/get-session";
12
+ type HenosiaOrganizationContext = {
13
+ id: string;
14
+ name: string;
15
+ logoUrl: string | null;
16
+ } | null;
17
+ declare const HENOSIA_ORGANIZATION_CTX_COOKIE = "henosia.org";
18
+ //#endregion
19
+ export { HenosiaOrganizationContext as i, HENOSIA_AUTH_SIGN_IN_PATH_NAME as n, HENOSIA_ORGANIZATION_CTX_COOKIE as r, HENOSIA_AUTH_GET_SESSION_PATH_NAME as t };
package/dist/shared.d.mts CHANGED
@@ -1,19 +1,3 @@
1
1
 
2
- //#region src/shared.d.ts
3
- declare const HENOSIA_AUTH_SIGN_IN_PATH_NAME = "/sign-in";
4
- /**
5
- * The pathname for better-auth's `/get-session` endpoint, used by the React `useSession` hook.
6
- *
7
- * `useSession` automatically refetches this endpoint on browser tab focus (and optionally on a polling
8
- * interval), which we leverage as a built-in keep-alive for the OIDC access/refresh tokens — see
9
- * `isPageOrRefreshTokenRequest` and the middleware special-case for this path.
10
- */
11
- declare const HENOSIA_AUTH_GET_SESSION_PATH_NAME = "/api/auth/get-session";
12
- type HenosiaOrganizationContext = {
13
- id: string;
14
- name: string;
15
- logoUrl: string | null;
16
- } | null;
17
- declare const HENOSIA_ORGANIZATION_CTX_COOKIE = "henosia.org";
18
- //#endregion
2
+ import { i as HenosiaOrganizationContext, n as HENOSIA_AUTH_SIGN_IN_PATH_NAME, r as HENOSIA_ORGANIZATION_CTX_COOKIE, t as HENOSIA_AUTH_GET_SESSION_PATH_NAME } from "./shared-BWt7Sysv.mjs";
19
3
  export { HENOSIA_AUTH_GET_SESSION_PATH_NAME, HENOSIA_AUTH_SIGN_IN_PATH_NAME, HENOSIA_ORGANIZATION_CTX_COOKIE, HenosiaOrganizationContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@henosia/app-next",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Henosia integration for Next.js apps: Provides Henosia Auth and Henosia Platform features like app switcher",
5
5
  "author": "Henosia",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -67,6 +67,7 @@
67
67
  "./auth/client": "./dist/auth/client.mjs",
68
68
  "./auth/middleware": "./dist/auth/middleware.mjs",
69
69
  "./auth/server": "./dist/auth/server.mjs",
70
+ "./auth/server-guards": "./dist/auth/server-guards.mjs",
70
71
  "./platform/app-switcher": "./dist/platform/app-switcher.mjs",
71
72
  "./shared": "./dist/shared.mjs",
72
73
  "./supabase/client": "./dist/supabase/client.mjs",