@tidecloak/nextjs 0.11.5 → 0.12.15
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
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
>
|
|
5
5
|
> If you're new to TideCloak, the fastest way to get started is with our official Next.js template:
|
|
6
6
|
> [`@tidecloak/create-nextjs`](../tidecloak-create-nextjs/README.md)
|
|
7
|
-
> It scaffolds a working project with authentication, middleware, and optional IAM setup
|
|
7
|
+
> It scaffolds a working project with authentication, middleware, and optional IAM setup - so you can start building right away.
|
|
8
8
|
>
|
|
9
9
|
>---
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
Secure your Next.js app with TideCloak: authentication, session management, data encryption, and edge-middleware integration.
|
|
13
13
|
|
|
14
|
+
[](https://www.youtube.com/watch?v=xsMwqMYS4eww "TideCloak your Next.js apps for provable security. Full walkthrough.")
|
|
15
|
+
|
|
14
16
|
---
|
|
15
17
|
|
|
16
18
|
## 1. Prerequisites
|
|
@@ -26,7 +28,7 @@ Before you begin, ensure you have the following:
|
|
|
26
28
|
* A [running](https://github.com/tide-foundation/tidecloak-gettingstarted) TideCloak server you have admin control over.
|
|
27
29
|
* IGA enabled realm
|
|
28
30
|
* A registered client in your realm with default user contexts approved and committed
|
|
29
|
-
* A valid
|
|
31
|
+
* A valid Tidecloak adapter JSON file (e.g., `tidecloakAdapter.json`)
|
|
30
32
|
|
|
31
33
|
> Note: Choose either the App Router or the Pages Router for your project. You only need one routing system active.
|
|
32
34
|
|
|
@@ -42,12 +44,12 @@ yarn add @tidecloak/nextjs
|
|
|
42
44
|
|
|
43
45
|
This bundle provides:
|
|
44
46
|
|
|
45
|
-
* `<TideCloakProvider>`
|
|
46
|
-
* `useTideCloak()` hook
|
|
47
|
-
* `verifyTideCloakToken()`
|
|
48
|
-
* `<Authenticated>` / `<Unauthenticated>`
|
|
49
|
-
* `doEncrypt()` / `doDecrypt()`
|
|
50
|
-
* `createTideCloakMiddleware()`
|
|
47
|
+
* `<TideCloakProvider>` - application-level context
|
|
48
|
+
* `useTideCloak()` hook - access tokens and auth actions
|
|
49
|
+
* `verifyTideCloakToken()` - server-side JWT verification
|
|
50
|
+
* `<Authenticated>` / `<Unauthenticated>` - UI guards
|
|
51
|
+
* `doEncrypt()` / `doDecrypt()` - tag-based encryption/decryption
|
|
52
|
+
* `createTideCloakMiddleware()` - Edge middleware for route protection (supports both Pages & App routers)
|
|
51
53
|
|
|
52
54
|
> **Note:** Installing this package automatically adds a `silent-check-sso.html` file to your `public` directory. This file is required for silent SSO checks; if it doesn’t exist, create it manually at `public/silent-check-sso.html` with the following content, otherwise the app will break:
|
|
53
55
|
>
|
|
@@ -65,7 +67,7 @@ This bundle provides:
|
|
|
65
67
|
|
|
66
68
|
To begin using the SDK, wrap your application with `<TideCloakProvider>`.
|
|
67
69
|
|
|
68
|
-
This makes authentication state, token access, and authorization tools available throughout your app. You only need to wrap once
|
|
70
|
+
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.
|
|
69
71
|
|
|
70
72
|
---
|
|
71
73
|
|
|
@@ -237,7 +239,7 @@ export default function Header() {
|
|
|
237
239
|
| `authenticated` | `boolean` | Whether the user is logged in. |
|
|
238
240
|
| `login()` / `logout()` | `() => void` | Trigger the login or logout flows. |
|
|
239
241
|
| `token`, `tokenExp` | `string`, `number` | Access token and its expiration timestamp. |
|
|
240
|
-
| Automatic token refresh | built-in | Tokens refresh silently on expiration
|
|
242
|
+
| Automatic token refresh | built-in | Tokens refresh silently on expiration-no manual setup needed. |
|
|
241
243
|
| `refreshToken()` | `() => Promise<boolean>` | Force a silent token renewal. |
|
|
242
244
|
| `getValueFromToken(key)` | `(key: string) => any` | Read a custom claim from the access token. |
|
|
243
245
|
| `getValueFromIdToken(key)` | `(key: string) => any` | Read a custom claim from the ID token. |
|
|
@@ -344,12 +346,11 @@ Place your middleware at the project root for both routers.
|
|
|
344
346
|
|
|
345
347
|
```ts
|
|
346
348
|
import { NextResponse } from 'next/server';
|
|
347
|
-
import
|
|
349
|
+
import tidecloakConfig from './tidecloakAdapter.json';
|
|
348
350
|
import { createTideCloakMiddleware } from '@tidecloak/nextjs/server/tidecloakMiddleware';
|
|
349
351
|
|
|
350
352
|
export default createTideCloakMiddleware({
|
|
351
|
-
config,
|
|
352
|
-
publicRoutes: ['/', '/about'],
|
|
353
|
+
config: tidecloakConfig,
|
|
353
354
|
protectedRoutes: {
|
|
354
355
|
'/admin/*': ['admin'],
|
|
355
356
|
'/api/private/*': ['user'],
|
|
@@ -415,10 +416,11 @@ export async function GET(req: NextRequest) {
|
|
|
415
416
|
|
|
416
417
|
## 9. Advanced & Best Practices
|
|
417
418
|
|
|
418
|
-
* **Auto-Refresh**: built into the provider
|
|
419
|
+
* **Auto-Refresh**: built into the provider-no manual timers.
|
|
419
420
|
* **Error Handling**: use the `initError` property from `useTideCloak`.
|
|
420
421
|
* **Custom Claims**: read via `getValueFromToken()` / `getValueFromIdToken()`.
|
|
421
422
|
* **Role-Based UI**: combine hooks & guard components for fine-grained control.
|
|
422
423
|
* **Lazy Initialization**: wrap `<TideCloakProvider>` around only protected sections in large apps.
|
|
423
424
|
|
|
424
425
|
---
|
|
426
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server';
|
|
2
2
|
import { verifyTideCloakToken } from '@tidecloak/verify';
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeProtectedRoutes } from './routerMatcher';
|
|
4
4
|
const DEFAULTS = {
|
|
5
5
|
protectedRoutes: {},
|
|
6
6
|
onRequest: undefined,
|
|
@@ -12,12 +12,11 @@ const DEFAULTS = {
|
|
|
12
12
|
* Example usage in your `middleware.ts`:
|
|
13
13
|
*
|
|
14
14
|
* ```ts
|
|
15
|
-
* import
|
|
15
|
+
* import tidecloakConfig from './tidecloakAdapter.json'
|
|
16
16
|
* import { createTideMiddleware } from 'tidecloak-nextjs/server/tidecloakMiddleware'
|
|
17
17
|
*
|
|
18
18
|
* export default createTideMiddleware({
|
|
19
|
-
* config:
|
|
20
|
-
* publicRoutes: ['/', '/about'],
|
|
19
|
+
* config: tidecloakConfig,
|
|
21
20
|
* protectedRoutes: {
|
|
22
21
|
* '/admin/*': ['admin'],
|
|
23
22
|
* '/api/private/*': ['user']
|
|
@@ -34,19 +33,13 @@ const DEFAULTS = {
|
|
|
34
33
|
* ```
|
|
35
34
|
*/
|
|
36
35
|
export function createTideCloakMiddleware(opts) {
|
|
37
|
-
var _a;
|
|
38
36
|
const settings = { ...DEFAULTS, ...opts };
|
|
39
|
-
// Prepare arrays of test functions for
|
|
40
|
-
const publicTests = ((_a = settings.publicRoutes) !== null && _a !== void 0 ? _a : []).map(normalizePattern);
|
|
37
|
+
// Prepare arrays of test functions for protected routes
|
|
41
38
|
const protectedTests = normalizeProtectedRoutes(settings.protectedRoutes);
|
|
42
39
|
return async function middleware(req) {
|
|
43
40
|
var _a;
|
|
44
41
|
const path = req.nextUrl.pathname;
|
|
45
42
|
try {
|
|
46
|
-
// Bypass auth entirely for configured public routes
|
|
47
|
-
if (publicTests.some(test => test(path, req))) {
|
|
48
|
-
return NextResponse.next();
|
|
49
|
-
}
|
|
50
43
|
// Extract the raw JWT from the specified cookie
|
|
51
44
|
const token = ((_a = req.cookies.get("kcToken")) === null || _a === void 0 ? void 0 : _a.value) || null;
|
|
52
45
|
// Allow custom logic before auth checks
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server';
|
|
2
2
|
import { verifyTideCloakToken } from '@tidecloak/verify';
|
|
3
|
-
import {
|
|
3
|
+
import { normalizeProtectedRoutes } from './routerMatcher';
|
|
4
4
|
const DEFAULTS = {
|
|
5
5
|
protectedRoutes: {},
|
|
6
6
|
onRequest: undefined,
|
|
@@ -12,12 +12,11 @@ const DEFAULTS = {
|
|
|
12
12
|
* Example usage in your `middleware.ts`:
|
|
13
13
|
*
|
|
14
14
|
* ```ts
|
|
15
|
-
* import
|
|
15
|
+
* import tidecloakConfig from './tidecloakAdapter.json'
|
|
16
16
|
* import { createTideMiddleware } from 'tidecloak-nextjs/server/tidecloakMiddleware'
|
|
17
17
|
*
|
|
18
18
|
* export default createTideMiddleware({
|
|
19
|
-
* config:
|
|
20
|
-
* publicRoutes: ['/', '/about'],
|
|
19
|
+
* config: tidecloakConfig,
|
|
21
20
|
* protectedRoutes: {
|
|
22
21
|
* '/admin/*': ['admin'],
|
|
23
22
|
* '/api/private/*': ['user']
|
|
@@ -34,19 +33,13 @@ const DEFAULTS = {
|
|
|
34
33
|
* ```
|
|
35
34
|
*/
|
|
36
35
|
export function createTideCloakMiddleware(opts) {
|
|
37
|
-
var _a;
|
|
38
36
|
const settings = { ...DEFAULTS, ...opts };
|
|
39
|
-
// Prepare arrays of test functions for
|
|
40
|
-
const publicTests = ((_a = settings.publicRoutes) !== null && _a !== void 0 ? _a : []).map(normalizePattern);
|
|
37
|
+
// Prepare arrays of test functions for protected routes
|
|
41
38
|
const protectedTests = normalizeProtectedRoutes(settings.protectedRoutes);
|
|
42
39
|
return async function middleware(req) {
|
|
43
40
|
var _a;
|
|
44
41
|
const path = req.nextUrl.pathname;
|
|
45
42
|
try {
|
|
46
|
-
// Bypass auth entirely for configured public routes
|
|
47
|
-
if (publicTests.some(test => test(path, req))) {
|
|
48
|
-
return NextResponse.next();
|
|
49
|
-
}
|
|
50
43
|
// Extract the raw JWT from the specified cookie
|
|
51
44
|
const token = ((_a = req.cookies.get("kcToken")) === null || _a === void 0 ? void 0 : _a.value) || null;
|
|
52
45
|
// Allow custom logic before auth checks
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
import {
|
|
2
|
+
import { ProtectedRoutesMap } from './routerMatcher';
|
|
3
3
|
interface JWK {
|
|
4
4
|
kid: string;
|
|
5
5
|
kty: string;
|
|
@@ -23,16 +23,13 @@ export interface TidecloakConfig {
|
|
|
23
23
|
/**
|
|
24
24
|
* Configuration options for TideCloak middleware.
|
|
25
25
|
*
|
|
26
|
-
* - `config`: Your
|
|
27
|
-
* - `publicRoutes`: Optional array of paths to exclude from auth, using globs, regex, or functions.
|
|
26
|
+
* - `config`: Your Tidecloak client adapter JSON.
|
|
28
27
|
* - `protectedRoutes`: Map of path patterns to arrays of required roles.
|
|
29
28
|
* - `onRequest`, `onSuccess`, `onFailure`, `onError`: Lifecycle hooks for custom logic.
|
|
30
29
|
*/
|
|
31
30
|
export interface TideMiddlewareOptions {
|
|
32
|
-
/**
|
|
31
|
+
/** Tidecloak client adapter JSON (downloaded from your Tidecloak realm settings) */
|
|
33
32
|
config: TidecloakConfig;
|
|
34
|
-
/** Routes that always bypass authentication */
|
|
35
|
-
publicRoutes?: RoutePattern[];
|
|
36
33
|
/** Routes requiring a verified token and specific roles */
|
|
37
34
|
protectedRoutes?: ProtectedRoutesMap;
|
|
38
35
|
/** Called before any auth logic; return a Response to short‑circuit */
|
|
@@ -56,12 +53,11 @@ export interface TideMiddlewareOptions {
|
|
|
56
53
|
* Example usage in your `middleware.ts`:
|
|
57
54
|
*
|
|
58
55
|
* ```ts
|
|
59
|
-
* import
|
|
56
|
+
* import tidecloakConfig from './tidecloakAdapter.json'
|
|
60
57
|
* import { createTideMiddleware } from 'tidecloak-nextjs/server/tidecloakMiddleware'
|
|
61
58
|
*
|
|
62
59
|
* export default createTideMiddleware({
|
|
63
|
-
* config:
|
|
64
|
-
* publicRoutes: ['/', '/about'],
|
|
60
|
+
* config: tidecloakConfig,
|
|
65
61
|
* protectedRoutes: {
|
|
66
62
|
* '/admin/*': ['admin'],
|
|
67
63
|
* '/api/private/*': ['user']
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tidecloakMiddleware.d.ts","sourceRoot":"","sources":["../../../src/server/tidecloakMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,
|
|
1
|
+
{"version":3,"file":"tidecloakMiddleware.d.ts","sourceRoot":"","sources":["../../../src/server/tidecloakMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,EAEL,kBAAkB,EACnB,MAAM,iBAAiB,CAAA;AAExB,UAAU,GAAG;IACT,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE;QACH,IAAI,EAAE,GAAG,EAAE,CAAC;KACb,CAAC;IAEF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,oFAAoF;IACpF,MAAM,EAAE,eAAe,CAAA;IACvB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,kBAAkB,CAAA;IACpC,uEAAuE;IACvE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,GAAG,EAAE,WAAW,KAAK,YAAY,GAAG,IAAI,CAAA;IACpF,kFAAkF;IAClF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,EAAE,GAAG,EAAE,WAAW,KAAK,YAAY,GAAG,IAAI,CAAA;IAC5F,0EAA0E;IAC1E,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,GAAG,EAAE,WAAW,KAAK,YAAY,GAAG,IAAI,CAAA;IACpF,wDAAwD;IACxD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,KAAK,YAAY,CAAA;CACvD;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,qBAAqB,IAMlC,KAAK,WAAW,oCAoDlD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tidecloak/nextjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.15",
|
|
4
4
|
"description": "TideCloak nextjs SDK",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"prepare": "npm run build"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@tidecloak/react": "^0.
|
|
52
|
-
"@tidecloak/verify": "^0.
|
|
51
|
+
"@tidecloak/react": "^0.12.15",
|
|
52
|
+
"@tidecloak/verify": "^0.12.15"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/react": "^19.1.8",
|