@tidecloak/nextjs 0.9.11 → 0.9.13
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 +167 -136
- package/dist/cjs/contexts/InternalTideCloakProvider.js +4 -0
- package/dist/cjs/contexts/TideCloakProvider.js +4 -0
- package/dist/cjs/index.js +4 -1
- package/dist/esm/contexts/InternalTideCloakProvider.js +4 -0
- package/dist/esm/contexts/TideCloakProvider.js +4 -0
- package/dist/esm/index.js +4 -1
- package/dist/types/contexts/InternalTideCloakProvider.d.ts +7 -0
- package/dist/types/contexts/InternalTideCloakProvider.d.ts.map +1 -0
- package/dist/types/contexts/TideCloakProvider.d.ts +4 -0
- package/dist/types/contexts/TideCloakProvider.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
# TideCloak NextJS SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> ## Quick Start Template
|
|
4
|
+
>
|
|
5
|
+
> If you're new to TideCloak, the fastest way to get started is with our official Next.js template:
|
|
6
|
+
> [`@tidecloak/create-nextjs`](../tidecloak-create-nextjs/README.md)
|
|
7
|
+
> It scaffolds a working project with authentication, middleware, and optional IAM setup — so you can start building right away.
|
|
8
|
+
>
|
|
9
|
+
>---
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Secure your Next.js app with TideCloak: authentication, session management, data encryption, and edge-middleware integration.
|
|
4
13
|
|
|
5
14
|
---
|
|
6
15
|
|
|
7
16
|
## 1. Prerequisites
|
|
8
17
|
|
|
9
|
-
Before you begin, ensure you have:
|
|
18
|
+
Before you begin, ensure you have the following:
|
|
10
19
|
|
|
11
|
-
* Next.js
|
|
12
|
-
* React 18 or later
|
|
13
|
-
* Node.js ≥18.17.0
|
|
14
|
-
* A running TideCloak server
|
|
15
|
-
* A registered client in your realm
|
|
20
|
+
* **Next.js**:
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
* App Router (recommended): Next.js 13.4 or later (for `layout.tsx` support)
|
|
23
|
+
* Pages Router (legacy): Next.js 12 or later (for `_app.tsx` support)
|
|
24
|
+
* **React 18** or later
|
|
25
|
+
* **Node.js ≥18.17.0**
|
|
26
|
+
* A [running](https://github.com/tide-foundation/tidecloak-gettingstarted) TideCloak server you have admin control over.
|
|
27
|
+
* IGA enabled realm
|
|
28
|
+
* A registered client in your realm with default user contexts approved and committed
|
|
29
|
+
* A valid Keycloak adapter JSON file (e.g., `tidecloakAdapter.json`)
|
|
18
30
|
|
|
19
|
-
|
|
31
|
+
> Note: Choose either the App Router or the Pages Router for your project. You only need one routing system active.
|
|
20
32
|
|
|
21
|
-
|
|
33
|
+
## 2. Install `@tidecloak/nextjs`
|
|
34
|
+
|
|
35
|
+
Add `@tidecloak/nextjs` to your project:
|
|
22
36
|
|
|
23
37
|
```bash
|
|
24
38
|
npm install @tidecloak/nextjs
|
|
@@ -28,51 +42,153 @@ yarn add @tidecloak/nextjs
|
|
|
28
42
|
|
|
29
43
|
This bundle provides:
|
|
30
44
|
|
|
31
|
-
* `<TideCloakProvider>`
|
|
32
|
-
* `useTideCloak()` hook
|
|
33
|
-
* `verifyTideCloakToken()`
|
|
34
|
-
* `<Authenticated>` / `<Unauthenticated>`
|
|
35
|
-
* `doEncrypt()` / `doDecrypt()`
|
|
36
|
-
* `createTideCloakMiddleware()`
|
|
45
|
+
* `<TideCloakProvider>` — application-level context
|
|
46
|
+
* `useTideCloak()` hook — access tokens and auth actions
|
|
47
|
+
* `verifyTideCloakToken()` — server-side JWT verification
|
|
48
|
+
* `<Authenticated>` / `<Unauthenticated>` — UI guards
|
|
49
|
+
* `doEncrypt()` / `doDecrypt()` — tag-based encryption/decryption
|
|
50
|
+
* `createTideCloakMiddleware()` — Edge middleware for route protection (supports both Pages & App routers)
|
|
37
51
|
|
|
38
52
|
---
|
|
39
53
|
|
|
40
54
|
## 3. Initialize the Provider
|
|
41
55
|
|
|
42
|
-
|
|
56
|
+
To begin using the SDK, wrap your application with `<TideCloakProvider>`.
|
|
57
|
+
|
|
58
|
+
This makes authentication state, token access, and authorization tools available throughout your app. You only need to wrap once—at the top level entry point depending on which routing system you're using.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### App Router
|
|
63
|
+
|
|
64
|
+
**File:** `/app/layout.tsx`
|
|
43
65
|
|
|
44
66
|
```tsx
|
|
45
|
-
'use client'
|
|
46
67
|
import React from 'react';
|
|
47
68
|
import { TideCloakProvider } from '@tidecloak/nextjs';
|
|
48
69
|
import adapter from '../tidecloakAdapter.json';
|
|
49
70
|
|
|
50
|
-
export default function
|
|
71
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
72
|
+
return (
|
|
73
|
+
<html lang="en">
|
|
74
|
+
<body>
|
|
75
|
+
<TideCloakProvider config={{ ...adapter }}>
|
|
76
|
+
{children}
|
|
77
|
+
</TideCloakProvider>
|
|
78
|
+
</body>
|
|
79
|
+
</html>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Description:** This `layout.tsx` is used by Next.js’s App Router. It defines the root HTML structure and wraps all nested pages and layouts with `TideCloakProvider`, making authentication context available everywhere in the `/app` directory.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### Pages Router
|
|
89
|
+
|
|
90
|
+
**File:** `/pages/_app.tsx`
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
import React from 'react';
|
|
94
|
+
import { TideCloakProvider } from '@tidecloak/nextjs';
|
|
95
|
+
import adapter from '../tidecloakAdapter.json';
|
|
96
|
+
|
|
97
|
+
function MyApp({ Component, pageProps }) {
|
|
51
98
|
return (
|
|
52
99
|
<TideCloakProvider config={adapter}>
|
|
53
|
-
<
|
|
100
|
+
<Component {...pageProps} />
|
|
54
101
|
</TideCloakProvider>
|
|
55
102
|
);
|
|
56
103
|
}
|
|
104
|
+
|
|
105
|
+
export default MyApp;
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Description:** The `_app.tsx` file is the entry point for the Pages Router. It wraps every page component in the `/pages` directory with `TideCloakProvider`, so that authentication state and methods are accessible across all your pages.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 4. Redirect URI Handling
|
|
113
|
+
|
|
114
|
+
TideCloak supports an optional `redirectUri` parameter. This is the URL users are sent to after login or logout.
|
|
115
|
+
|
|
116
|
+
If omitted, it defaults to:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
`${window.location.origin}/auth/redirect`
|
|
57
120
|
```
|
|
58
121
|
|
|
59
|
-
|
|
122
|
+
> If your app runs at `http://localhost:3000`, then by default users will be redirected to `http://localhost:3000/auth/redirect` after login or logout.
|
|
123
|
+
>
|
|
124
|
+
> If that route doesn't exist in your project, you must create it or explicitly define a different `redirectUri` in your TideCloak config.
|
|
125
|
+
|
|
126
|
+
If you use the default, you **must create a page** at `/auth/redirect` in your app.
|
|
127
|
+
|
|
128
|
+
You can customize this URI in your provider config:
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
<TideCloakProvider config={{ ...adapter, redirectUri: 'https://yourapp.com/auth/callback' }}>
|
|
132
|
+
{children}
|
|
133
|
+
</TideCloakProvider>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Example: `/app/auth/redirect/page.tsx`
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
'use client';
|
|
140
|
+
|
|
141
|
+
import { useEffect } from 'react';
|
|
142
|
+
import { useRouter } from 'next/navigation';
|
|
143
|
+
import { useTideCloak } from '@tidecloak/nextjs';
|
|
60
144
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
145
|
+
export default function RedirectPage() {
|
|
146
|
+
const { authenticated, isInitializing, logout } = useTideCloak();
|
|
147
|
+
const router = useRouter();
|
|
148
|
+
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
const params = new URLSearchParams(window.location.search);
|
|
151
|
+
if (params.get("auth") === "failed") {
|
|
152
|
+
sessionStorage.setItem("tokenExpired", "true");
|
|
153
|
+
logout();
|
|
154
|
+
}
|
|
155
|
+
}, []);
|
|
156
|
+
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
if (!isInitializing) {
|
|
159
|
+
router.push(authenticated ? '/home' : '/');
|
|
160
|
+
}
|
|
161
|
+
}, [authenticated, isInitializing, router]);
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<div style={{
|
|
165
|
+
minHeight: '100vh',
|
|
166
|
+
display: 'flex',
|
|
167
|
+
alignItems: 'center',
|
|
168
|
+
justifyContent: 'center',
|
|
169
|
+
fontSize: '1rem',
|
|
170
|
+
color: '#555',
|
|
171
|
+
}}>
|
|
172
|
+
<p>Waiting for authentication...</p>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
This page helps finalize the login or logout flow, and also reacts to token expiration events that may have triggered a redirect from the middleware.
|
|
64
179
|
|
|
65
180
|
---
|
|
66
181
|
|
|
67
182
|
## 4. Using the `useTideCloak` Hook
|
|
68
183
|
|
|
69
|
-
Use this hook anywhere to manage
|
|
184
|
+
Use this hook anywhere in your React component tree to manage authentication:
|
|
70
185
|
|
|
71
186
|
```tsx
|
|
72
187
|
'use client'
|
|
188
|
+
import React from 'react';
|
|
73
189
|
import { useTideCloak } from '@tidecloak/nextjs';
|
|
74
190
|
|
|
75
|
-
function Header() {
|
|
191
|
+
export default function Header() {
|
|
76
192
|
const {
|
|
77
193
|
authenticated,
|
|
78
194
|
login,
|
|
@@ -111,7 +227,7 @@ function Header() {
|
|
|
111
227
|
| `authenticated` | `boolean` | Whether the user is logged in. |
|
|
112
228
|
| `login()` / `logout()` | `() => void` | Trigger the login or logout flows. |
|
|
113
229
|
| `token`, `tokenExp` | `string`, `number` | Access token and its expiration timestamp. |
|
|
114
|
-
| Automatic token refresh | built-in | Tokens refresh silently on expiration
|
|
230
|
+
| Automatic token refresh | built-in | Tokens refresh silently on expiration—no manual setup needed. |
|
|
115
231
|
| `refreshToken()` | `() => Promise<boolean>` | Force a silent token renewal. |
|
|
116
232
|
| `getValueFromToken(key)` | `(key: string) => any` | Read a custom claim from the access token. |
|
|
117
233
|
| `getValueFromIdToken(key)` | `(key: string) => any` | Read a custom claim from the ID token. |
|
|
@@ -123,18 +239,19 @@ function Header() {
|
|
|
123
239
|
|
|
124
240
|
## 5. Guard Components
|
|
125
241
|
|
|
126
|
-
Use
|
|
242
|
+
Use these components to conditionally render UI based on auth state:
|
|
127
243
|
|
|
128
244
|
```tsx
|
|
129
245
|
'use client'
|
|
246
|
+
import React from 'react';
|
|
130
247
|
import { Authenticated, Unauthenticated } from '@tidecloak/nextjs';
|
|
131
248
|
|
|
132
|
-
function Dashboard() {
|
|
249
|
+
export default function Dashboard() {
|
|
133
250
|
return (
|
|
134
251
|
<>
|
|
135
252
|
<Authenticated>
|
|
136
253
|
<h1>Dashboard</h1>
|
|
137
|
-
{/* Protected widgets */}
|
|
254
|
+
{/* Protected widgets here */}
|
|
138
255
|
</Authenticated>
|
|
139
256
|
|
|
140
257
|
<Unauthenticated>
|
|
@@ -152,65 +269,38 @@ function Dashboard() {
|
|
|
152
269
|
|
|
153
270
|
## 6. Encrypting & Decrypting Data
|
|
154
271
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
### Syntax Overview
|
|
272
|
+
Protect sensitive payloads using tag-based encryption/decryption:
|
|
158
273
|
|
|
159
274
|
```ts
|
|
160
275
|
// Encrypt payloads:
|
|
161
276
|
const encryptedArray = await doEncrypt([
|
|
162
|
-
{ data:
|
|
163
|
-
// …
|
|
277
|
+
{ data: { email: 'user@example.com' }, tags: ['email'] },
|
|
164
278
|
]);
|
|
165
279
|
|
|
166
280
|
// Decrypt blobs:
|
|
167
281
|
const decryptedArray = await doDecrypt([
|
|
168
|
-
{ encrypted:
|
|
169
|
-
// …
|
|
282
|
+
{ encrypted: encryptedArray[0], tags: ['email'] },
|
|
170
283
|
]);
|
|
171
284
|
```
|
|
172
285
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
### Permissions
|
|
176
|
-
|
|
177
|
-
* **Encryption** requires roles `tide_<tag>.selfencrypt` for each tag.
|
|
178
|
-
* **Decryption** requires roles `tide_<tag>.selfdecrypt` for each tag.
|
|
286
|
+
* **Permissions**: Encryption requires roles `tide_<tag>.selfencrypt`; decryption requires `tide_<tag>.selfdecrypt`.
|
|
287
|
+
* **Order guarantee**: Output array preserves input order.
|
|
179
288
|
|
|
180
289
|
---
|
|
181
290
|
|
|
182
291
|
## 7. Edge Middleware with TideCloak
|
|
183
292
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
* **Pages Router**: Place your `middleware.ts` file at the project root alongside `pages/`. The exported middleware will apply to both page and API routes.
|
|
187
|
-
* **App Router**: Put `middleware.ts` at the project root (or inside `src/`). It integrates with `/app` routes and layouts, protecting both server components and route handlers.
|
|
188
|
-
|
|
189
|
-
### 7.1 Installation
|
|
190
|
-
|
|
191
|
-
No additional install-middleware is included in `@tidecloak/nextjs`.
|
|
192
|
-
|
|
193
|
-
### 7.2 Options
|
|
293
|
+
Place your middleware at the project root for both routers.
|
|
194
294
|
|
|
195
|
-
|
|
196
|
-
* **`publicRoutes`** (`RoutePattern[]`): Paths to bypass authentication (strings/globs/regex/functions).
|
|
197
|
-
* **`protectedRoutes`** (`ProtectedRoutesMap`): Map of path patterns to arrays of required roles.
|
|
198
|
-
* **`onRequest`**<br>`(ctx: { token: string | null }, req: NextRequest) => NextResponse | void`<br>Hook before auth logic; can short-circuit by returning a `NextResponse`.
|
|
199
|
-
* **`onSuccess`**<br>`(ctx: { payload: Record<string, any> }, req: NextRequest) => NextResponse | void`<br>Hook after successful auth & role checks; override the response by returning one.
|
|
200
|
-
* **`onFailure`**<br>`(ctx: { token: string | null }, req: NextRequest) => NextResponse | void`<br>Hook when auth or role check fails; return a `NextResponse` to override.
|
|
201
|
-
* **`onError`**<br>`(err: any, req: NextRequest) => NextResponse`<br>Hook for unexpected errors in middleware logic.
|
|
202
|
-
|
|
203
|
-
### 7.3 Example Usage
|
|
204
|
-
|
|
205
|
-
Place the following `middleware.ts` at your project root (works for both Pages and App routers) to protect both page routes and API handlers:
|
|
295
|
+
**File:** `/middleware.ts`
|
|
206
296
|
|
|
207
297
|
```ts
|
|
208
298
|
import { NextResponse } from 'next/server';
|
|
209
|
-
import
|
|
299
|
+
import config from './tidecloak.config.json';
|
|
210
300
|
import { createTideCloakMiddleware } from '@tidecloak/nextjs/server/tidecloakMiddleware';
|
|
211
301
|
|
|
212
302
|
export default createTideCloakMiddleware({
|
|
213
|
-
config
|
|
303
|
+
config,
|
|
214
304
|
publicRoutes: ['/', '/about'],
|
|
215
305
|
protectedRoutes: {
|
|
216
306
|
'/admin/*': ['admin'],
|
|
@@ -222,122 +312,63 @@ export default createTideCloakMiddleware({
|
|
|
222
312
|
|
|
223
313
|
export const config = {
|
|
224
314
|
matcher: [
|
|
225
|
-
'/((?!_next|[^?]
|
|
315
|
+
'/((?!_next|[^?]*\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico)).*)',
|
|
226
316
|
'/api/(.*)',
|
|
227
317
|
],
|
|
228
318
|
runtime: 'edge',
|
|
229
319
|
};
|
|
230
320
|
```
|
|
231
321
|
|
|
232
|
-
**
|
|
233
|
-
|
|
234
|
-
1. Bypass any `publicRoutes`
|
|
235
|
-
2. Read the `kcToken` cookie
|
|
236
|
-
3. Invoke `onRequest` hook (if provided)
|
|
237
|
-
4. Match path against `protectedRoutes` patterns
|
|
238
|
-
5. Verify signature, issuer, and roles via `verifyTideCloakToken()`
|
|
239
|
-
6. On success: `onSuccess` hook or `NextResponse.next()`
|
|
240
|
-
7. On failure: `onFailure` hook or default 403 response
|
|
241
|
-
8. On unexpected errors: `onError` hook
|
|
322
|
+
**Description:** The `middleware.ts` file runs at the Edge runtime before any page or API request. It applies authentication and role-based access control globally, using your adapter settings to verify tokens and redirect or rewrite responses as needed.
|
|
242
323
|
|
|
243
324
|
---
|
|
244
325
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
You can verify TideCloak-issued JWTs on your server or API routes using `verifyTideCloakToken`:
|
|
248
|
-
|
|
249
|
-
```ts
|
|
250
|
-
import { verifyTideCloakToken } from '@tidecloak/nextjs/server';
|
|
251
|
-
|
|
252
|
-
// Returns the decoded payload if valid and roles pass, otherwise null
|
|
253
|
-
const payload = await verifyTideCloakToken(
|
|
254
|
-
config, // Your TideCloak adapter JSON
|
|
255
|
-
token, // Raw access token to verify
|
|
256
|
-
['admin', 'user'] // Optional roles; user must have at least one
|
|
257
|
-
);
|
|
258
|
-
|
|
259
|
-
if (!payload) {
|
|
260
|
-
// Invalid token or insufficient roles
|
|
261
|
-
}
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
Under the hood, it uses `jose` for cryptographic verification and key management:
|
|
265
|
-
|
|
266
|
-
```ts
|
|
267
|
-
import { jwtVerify, createLocalJWKSet, createRemoteJWKSet } from 'jose';
|
|
268
|
-
|
|
269
|
-
export async function verifyTideCloakToken(config, token, allowedRoles = []) {
|
|
270
|
-
// Implementation checks token presence, issuer, signature,
|
|
271
|
-
// authorized party (azp), and at least one allowed role.
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
**Parameters:**
|
|
276
|
-
|
|
277
|
-
* `config` (`object`): Your TideCloak adapter JSON (parsed Keycloak config).
|
|
278
|
-
* `token` (`string`): Access token string to verify.
|
|
279
|
-
* `allowedRoles` (`string[]`, optional): Array of realm or client roles; user must have at least one.
|
|
280
|
-
|
|
281
|
-
**Returns:**
|
|
282
|
-
|
|
283
|
-
* `Promise<object | null>`: Decoded JWT payload if valid and role check passes; otherwise `null`.
|
|
284
|
-
|
|
285
|
-
### Example: Protecting an API Route
|
|
326
|
+
## 8. Server‑Side Token Verification
|
|
286
327
|
|
|
287
|
-
|
|
328
|
+
### Pages Router
|
|
288
329
|
|
|
289
|
-
|
|
330
|
+
**File:** `/pages/api/secure.ts`
|
|
290
331
|
|
|
291
332
|
```ts
|
|
292
|
-
// pages/api/secure.ts
|
|
293
333
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
294
334
|
import { verifyTideCloakToken } from '@tidecloak/nextjs/server';
|
|
295
335
|
import config from '../../tidecloakAdapter.json';
|
|
296
336
|
|
|
297
337
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
298
|
-
// Extract token from cookie or Authorization header
|
|
299
338
|
const token = req.cookies.kcToken || req.headers.authorization?.split(' ')[1] || '';
|
|
300
|
-
|
|
301
|
-
// Verify signature, issuer, and roles (e.g., 'user')
|
|
302
339
|
const payload = await verifyTideCloakToken(config, token, ['user']);
|
|
303
340
|
if (!payload) {
|
|
304
341
|
return res.status(401).json({ error: 'Unauthorized' });
|
|
305
342
|
}
|
|
306
|
-
|
|
307
|
-
// Proceed with secure logic
|
|
308
343
|
res.status(200).json({ data: 'Secure data response' });
|
|
309
344
|
}
|
|
310
345
|
```
|
|
311
346
|
|
|
312
|
-
|
|
347
|
+
### App Router
|
|
348
|
+
|
|
349
|
+
**File:** `/app/api/secure/route.ts`
|
|
313
350
|
|
|
314
351
|
```ts
|
|
315
|
-
// app/api/secure/route.ts
|
|
316
352
|
import { NextRequest, NextResponse } from 'next/server';
|
|
317
353
|
import { verifyTideCloakToken } from '@tidecloak/nextjs/server';
|
|
318
354
|
import config from '../../../tidecloakAdapter.json';
|
|
319
355
|
|
|
320
356
|
export async function GET(req: NextRequest) {
|
|
321
|
-
// Extract token from cookie
|
|
322
357
|
const token = req.cookies.get('kcToken')?.value || '';
|
|
323
|
-
|
|
324
|
-
// Verify signature, issuer, and roles (e.g., 'user')
|
|
325
358
|
const payload = await verifyTideCloakToken(config, token, ['user']);
|
|
326
359
|
if (!payload) {
|
|
327
360
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
328
361
|
}
|
|
329
|
-
|
|
330
|
-
// Proceed with secure logic
|
|
331
362
|
return NextResponse.json({ data: 'Secure data response' });
|
|
332
363
|
}
|
|
333
364
|
```
|
|
334
365
|
|
|
335
366
|
---
|
|
336
367
|
|
|
337
|
-
##
|
|
368
|
+
## 9. Advanced & Best Practices
|
|
338
369
|
|
|
339
|
-
* **Auto-Refresh**: built into the provider
|
|
340
|
-
* **Error Handling**: use the `initError`
|
|
370
|
+
* **Auto-Refresh**: built into the provider—no manual timers.
|
|
371
|
+
* **Error Handling**: use the `initError` property from `useTideCloak`.
|
|
341
372
|
* **Custom Claims**: read via `getValueFromToken()` / `getValueFromIdToken()`.
|
|
342
373
|
* **Role-Based UI**: combine hooks & guard components for fine-grained control.
|
|
343
374
|
* **Lazy Initialization**: wrap `<TideCloakProvider>` around only protected sections in large apps.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { InternalTideCloakProvider } from "./InternalTideCloakProvider";
|
|
4
|
+
export const TideCloakProvider = ({ config, children }) => (_jsx(InternalTideCloakProvider, { config: config, children: children }));
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
|
+
import { useTideCloak, Authenticated, Unauthenticated, TideCloakContextProvider } from '@tidecloak/react';
|
|
3
|
+
export { useTideCloak, Authenticated, Unauthenticated, TideCloakContextProvider };
|
|
4
|
+
export { TideCloakProvider } from "./contexts/TideCloakProvider";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { InternalTideCloakProvider } from "./InternalTideCloakProvider";
|
|
4
|
+
export const TideCloakProvider = ({ config, children }) => (_jsx(InternalTideCloakProvider, { config: config, children: children }));
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
|
+
import { useTideCloak, Authenticated, Unauthenticated, TideCloakContextProvider } from '@tidecloak/react';
|
|
3
|
+
export { useTideCloak, Authenticated, Unauthenticated, TideCloakContextProvider };
|
|
4
|
+
export { TideCloakProvider } from "./contexts/TideCloakProvider";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactNode, FC } from "react";
|
|
2
|
+
export interface TideCloakProviderProps {
|
|
3
|
+
config: Record<string, any>;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare const InternalTideCloakProvider: FC<TideCloakProviderProps>;
|
|
7
|
+
//# sourceMappingURL=InternalTideCloakProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InternalTideCloakProvider.d.ts","sourceRoot":"","sources":["../../../src/contexts/InternalTideCloakProvider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGtC,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,yBAAyB,EAAG,EAAE,CAAC,sBAAsB,CAIjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TideCloakProvider.d.ts","sourceRoot":"","sources":["../../../src/contexts/TideCloakProvider.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAC3B,OAAO,EAA6B,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGhG,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,sBAAsB,CAIxD,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { useTideCloak, Authenticated, Unauthenticated, TideCloakContextProvider } from '@tidecloak/react';
|
|
2
|
+
export { useTideCloak, Authenticated, Unauthenticated, TideCloakContextProvider };
|
|
3
|
+
export { TideCloakProvider } from "./contexts/TideCloakProvider";
|
|
2
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,wBAAwB,EACzB,CAAC;AACF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tidecloak/nextjs",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.13",
|
|
4
4
|
"description": "TideCloak nextjs SDK",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"oidc",
|
|
35
35
|
"oauth2",
|
|
36
36
|
"authorization",
|
|
37
|
-
"react"
|
|
37
|
+
"react",
|
|
38
|
+
"nextjs"
|
|
38
39
|
],
|
|
39
40
|
"peerDependencies": {
|
|
40
41
|
"next": ">=13",
|
|
@@ -47,8 +48,8 @@
|
|
|
47
48
|
"prepare": "npm run build"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
|
-
"@tidecloak/react": "^0.9.
|
|
51
|
-
"@tidecloak/verify": "^0.9.
|
|
51
|
+
"@tidecloak/react": "^0.9.13",
|
|
52
|
+
"@tidecloak/verify": "^0.9.13"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"@types/react": "^19.1.8",
|