@zitadel/sdk-next 0.1.0-alpha.9 → 0.1.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.
Files changed (48) hide show
  1. package/README.md +207 -37
  2. package/dist/auth.d.ts +66 -13
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +162 -7
  5. package/dist/client.d.ts +27 -2
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +29 -9
  8. package/dist/components.d.ts +16 -0
  9. package/dist/components.d.ts.map +1 -0
  10. package/dist/components.js +15 -0
  11. package/dist/context.d.ts +21 -10
  12. package/dist/context.d.ts.map +1 -0
  13. package/dist/context.js +24 -8
  14. package/dist/index.d.ts +16 -9
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +13 -24
  17. package/dist/jsx.d.ts +5 -0
  18. package/dist/lib/jwt.d.ts +9 -0
  19. package/dist/lib/jwt.d.ts.map +1 -0
  20. package/dist/lib/jwt.js +7 -0
  21. package/dist/middleware.d.ts +19 -11
  22. package/dist/middleware.d.ts.map +1 -0
  23. package/dist/middleware.js +304 -9
  24. package/dist/provider.d.ts +52 -0
  25. package/dist/provider.d.ts.map +1 -0
  26. package/dist/provider.js +75 -0
  27. package/dist/react.d.ts +26 -0
  28. package/dist/react.d.ts.map +1 -0
  29. package/dist/react.js +24 -0
  30. package/dist/server.d.ts +13 -2
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +10 -7
  33. package/dist/session.d.ts +77 -0
  34. package/dist/session.d.ts.map +1 -0
  35. package/dist/session.js +156 -0
  36. package/dist/types.d.ts +8 -3
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/types.js +1 -1
  39. package/dist/useAuth.d.ts +17 -5
  40. package/dist/useAuth.d.ts.map +1 -0
  41. package/dist/useAuth.js +18 -7
  42. package/package.json +46 -31
  43. package/dist/chunk-2BFQLJQE.js +0 -27
  44. package/dist/chunk-4KENHIG4.js +0 -222
  45. package/dist/chunk-6F4PWJZI.js +0 -0
  46. package/dist/chunk-B7S6XMT3.js +0 -41
  47. package/dist/chunk-OCZMYSFX.js +0 -13
  48. package/dist/chunk-XTCHTAIQ.js +0 -12
@@ -1,27 +0,0 @@
1
- // src/context.tsx
2
- import { createContext, useContext } from "react";
3
- import { jsx } from "react/jsx-runtime";
4
- var defaultValue = { isAuthenticated: false, session: null };
5
- var NextgenAuthContext = createContext(defaultValue);
6
- function NextgenProvider({
7
- session,
8
- children
9
- }) {
10
- let value;
11
- if (!session) {
12
- value = { isAuthenticated: false, session: null };
13
- } else if ("isAuthenticated" in session) {
14
- value = session;
15
- } else {
16
- value = { isAuthenticated: true, session };
17
- }
18
- return /* @__PURE__ */ jsx(NextgenAuthContext.Provider, { value, children });
19
- }
20
- function useAuthContext() {
21
- return useContext(NextgenAuthContext);
22
- }
23
-
24
- export {
25
- NextgenProvider,
26
- useAuthContext
27
- };
@@ -1,222 +0,0 @@
1
- import {
2
- base64UrlDecode,
3
- verifyJwt
4
- } from "./chunk-OCZMYSFX.js";
5
-
6
- // src/middleware.ts
7
- import {
8
- HOP_BY_HOP,
9
- INTERNAL_HEADERS,
10
- filterResponseHeaders,
11
- matchesRoutes
12
- } from "@zitadel/sdk-core/middleware";
13
- import { NextResponse } from "next/server";
14
- function tunnelHeaders(req, extra) {
15
- const headers = new Headers(req.headers);
16
- headers.delete("x-middleware-override-headers");
17
- const injectedNames = [];
18
- for (const [name, value] of Object.entries(extra)) {
19
- headers.set(name, value);
20
- headers.set(`x-middleware-request-${name}`, value);
21
- injectedNames.push(name);
22
- }
23
- headers.set("x-middleware-override-headers", injectedNames.join(","));
24
- return headers;
25
- }
26
- async function nextgenMiddleware(req, options = {}) {
27
- const {
28
- url = process.env.ZITADEL_URL ?? "http://localhost:8080",
29
- proxyPath = "/__nextgen",
30
- protectedRoutes = [],
31
- ignoredRoutes = [],
32
- loginPath = "/login",
33
- allowedAlgorithms = ["RS256", "ES256"],
34
- clockSkewMs = 5e3,
35
- audience,
36
- allowedTokenTypes = ["JWT", "at+JWT"],
37
- jwksTimeoutMs,
38
- proxyTimeoutMs = 5e3,
39
- onExchangeResponse
40
- } = options;
41
- if (!loginPath.startsWith("/") || loginPath.startsWith("//")) {
42
- throw new Error(
43
- `[nextgen] loginPath must be a relative path starting with a single "/". Received: "${loginPath}". Using an absolute or protocol-relative URL would allow open-redirect attacks.`
44
- );
45
- }
46
- const { pathname } = new URL(req.url);
47
- if (matchesRoutes(pathname, ignoredRoutes)) {
48
- const headers = tunnelHeaders(req, { "x-nextgen-auth-token": "" });
49
- return NextResponse.next({ request: { headers } });
50
- }
51
- if (pathname === proxyPath || pathname.startsWith(`${proxyPath}/`)) {
52
- return proxyRequest(
53
- req,
54
- url,
55
- proxyPath,
56
- proxyTimeoutMs,
57
- onExchangeResponse
58
- );
59
- }
60
- return handleAuth(req, {
61
- url,
62
- protectedRoutes,
63
- loginPath,
64
- allowedAlgorithms,
65
- clockSkewMs,
66
- audience,
67
- allowedTokenTypes,
68
- jwksTimeoutMs,
69
- pathname
70
- });
71
- }
72
- var DECODER = new TextDecoder();
73
- function isJwtShaped(token) {
74
- const parts = token.split(".");
75
- if (parts.length < 3 || !parts[0]) return false;
76
- try {
77
- const header = JSON.parse(
78
- DECODER.decode(base64UrlDecode(parts[0]))
79
- );
80
- return typeof header?.alg === "string" && !("enc" in header);
81
- } catch {
82
- return false;
83
- }
84
- }
85
- async function validateOpaqueSessionToken(token, issuerUrl, timeoutMs) {
86
- try {
87
- const res = await fetch(`${issuerUrl}/sessions/me`, {
88
- method: "GET",
89
- headers: { cookie: `__nextgen_session=${token}` },
90
- signal: AbortSignal.timeout(timeoutMs)
91
- });
92
- return res.ok;
93
- } catch {
94
- return false;
95
- }
96
- }
97
- async function proxyRequest(req, authUrl, proxyPath, proxyTimeoutMs, onExchangeResponse) {
98
- const url = new URL(req.url);
99
- const suffix = url.pathname.slice(proxyPath.length);
100
- const target = `${authUrl}${suffix}${url.search}`;
101
- const upstreamHeaders = new Headers();
102
- for (const [key, value] of req.headers.entries()) {
103
- const lower = key.toLowerCase();
104
- if (!HOP_BY_HOP.has(lower) && !INTERNAL_HEADERS.has(lower)) {
105
- upstreamHeaders.set(key, value);
106
- }
107
- }
108
- const directIp = req.ip ?? req.headers.get("x-real-ip");
109
- if (directIp) {
110
- const existingXff = upstreamHeaders.get("x-forwarded-for");
111
- upstreamHeaders.set(
112
- "x-forwarded-for",
113
- existingXff ? `${existingXff}, ${directIp}` : directIp
114
- );
115
- }
116
- if (!upstreamHeaders.has("x-forwarded-host")) {
117
- upstreamHeaders.set("x-forwarded-host", url.host);
118
- }
119
- if (!upstreamHeaders.has("x-forwarded-proto")) {
120
- upstreamHeaders.set("x-forwarded-proto", url.protocol.replace(":", ""));
121
- }
122
- const hasBody = !["GET", "HEAD"].includes(req.method);
123
- const isExchangeRequest = req.method === "POST" && suffix.startsWith("/sessions/exchange");
124
- if (isExchangeRequest && !upstreamHeaders.has("authorization")) {
125
- const projectId = url.searchParams.get("project_id");
126
- if (projectId) {
127
- upstreamHeaders.set("authorization", `Bearer sk_${projectId}`);
128
- }
129
- }
130
- const bodyBuffer = hasBody ? await req.arrayBuffer() : void 0;
131
- const upstream = await fetch(target, {
132
- method: req.method,
133
- headers: upstreamHeaders,
134
- body: bodyBuffer,
135
- redirect: "manual",
136
- signal: AbortSignal.timeout(proxyTimeoutMs)
137
- });
138
- const responseHeaders = filterResponseHeaders(upstream.headers);
139
- const setCookies = upstream.headers.getSetCookie?.() ?? [];
140
- for (const cookie of setCookies) {
141
- responseHeaders.append("set-cookie", cookie);
142
- }
143
- let response = new Response(upstream.body, {
144
- status: upstream.status,
145
- headers: responseHeaders
146
- });
147
- if (isExchangeRequest && onExchangeResponse) {
148
- response = await onExchangeResponse(response);
149
- }
150
- return response;
151
- }
152
- async function handleAuth(req, opts) {
153
- const {
154
- url,
155
- protectedRoutes,
156
- loginPath,
157
- allowedAlgorithms,
158
- clockSkewMs,
159
- audience,
160
- allowedTokenTypes,
161
- jwksTimeoutMs,
162
- pathname
163
- } = opts;
164
- const authHeader = req.headers.get("authorization");
165
- const bearerToken = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : null;
166
- const cookieToken = req.cookies.get("__nextgen_session")?.value ?? null;
167
- const token = bearerToken ?? cookieToken;
168
- const payload = token ? await verifyJwt(token, {
169
- issuerUrl: url,
170
- allowedAlgorithms,
171
- clockSkewMs,
172
- audience,
173
- allowedTokenTypes,
174
- jwksTimeoutMs
175
- }) : null;
176
- if (payload && token && payload.sub) {
177
- const tunnelled2 = tunnelHeaders(req, { "x-nextgen-auth-token": token });
178
- return NextResponse.next({ request: { headers: tunnelled2 } });
179
- }
180
- if (!payload && cookieToken && !isJwtShaped(cookieToken)) {
181
- const isValid = await validateOpaqueSessionToken(
182
- cookieToken,
183
- url,
184
- jwksTimeoutMs ?? 5e3
185
- );
186
- if (isValid) {
187
- const tunnelled2 = tunnelHeaders(req, {
188
- "x-nextgen-auth-token": cookieToken
189
- });
190
- return NextResponse.next({ request: { headers: tunnelled2 } });
191
- }
192
- }
193
- const tunnelled = tunnelHeaders(req, { "x-nextgen-auth-token": "" });
194
- const staleNextgenCookies = req.cookies.getAll().filter((c) => c.name.startsWith("__nextgen"));
195
- if (matchesRoutes(pathname, protectedRoutes)) {
196
- const loginUrl = new URL(loginPath, req.url);
197
- loginUrl.searchParams.set("next", pathname);
198
- const redirect = NextResponse.redirect(loginUrl, { status: 302 });
199
- for (const cookie of staleNextgenCookies) {
200
- redirect.cookies.delete(cookie.name);
201
- }
202
- return redirect;
203
- }
204
- const response = NextResponse.next({ request: { headers: tunnelled } });
205
- for (const cookie of staleNextgenCookies) {
206
- response.cookies.delete(cookie.name);
207
- }
208
- return response;
209
- }
210
- function createProxy(config, options = {}) {
211
- const mergedOptions = {
212
- ...options,
213
- proxyPath: config.proxyPath,
214
- url: config.url
215
- };
216
- return (req) => nextgenMiddleware(req, mergedOptions);
217
- }
218
-
219
- export {
220
- nextgenMiddleware,
221
- createProxy
222
- };
File without changes
@@ -1,41 +0,0 @@
1
- import {
2
- decodeJwt
3
- } from "./chunk-OCZMYSFX.js";
4
-
5
- // src/auth.ts
6
- import { headers } from "next/headers";
7
- async function auth() {
8
- const headerStore = await headers();
9
- const token = headerStore.get("x-nextgen-auth-token");
10
- if (!token) {
11
- return { isAuthenticated: false, session: null };
12
- }
13
- try {
14
- const { payload } = decodeJwt(token);
15
- if (payload.sub) {
16
- return {
17
- isAuthenticated: true,
18
- session: {
19
- userId: payload.sub,
20
- email: payload.email ?? null,
21
- name: payload.name ?? null,
22
- token
23
- }
24
- };
25
- }
26
- } catch {
27
- }
28
- return {
29
- isAuthenticated: true,
30
- session: {
31
- userId: "unknown",
32
- email: null,
33
- name: null,
34
- token
35
- }
36
- };
37
- }
38
-
39
- export {
40
- auth
41
- };
@@ -1,13 +0,0 @@
1
- // src/lib/jwt.ts
2
- import {
3
- JWKS_TTL_MS,
4
- base64UrlDecode,
5
- decodeJwt,
6
- verifyJwt
7
- } from "@zitadel/sdk-core/jwt";
8
-
9
- export {
10
- base64UrlDecode,
11
- decodeJwt,
12
- verifyJwt
13
- };
@@ -1,12 +0,0 @@
1
- import {
2
- useAuthContext
3
- } from "./chunk-2BFQLJQE.js";
4
-
5
- // src/useAuth.ts
6
- function useAuth() {
7
- return useAuthContext();
8
- }
9
-
10
- export {
11
- useAuth
12
- };