@tidecloak/verify 0.14.32-staging → 0.14.33
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 +27 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,12 +30,12 @@ import { verifyTideCloakToken } from '@tidecloak/verify';
|
|
|
30
30
|
|
|
31
31
|
| Parameter | Type | Description |
|
|
32
32
|
| -------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
-
| `config` | `object` | Your
|
|
33
|
+
| `config` | `object` | Your `tidecloak.json` adapter config (the client configuration you download from your realm settings). |
|
|
34
34
|
| `token` | `string` | The raw JWT (access token) to verify. |
|
|
35
35
|
| `allowedRoles` | `string[]` (optional) | Array of Tidecloak realm or client roles. If provided, the user must have at least one of these roles in their token. |
|
|
36
36
|
|
|
37
37
|
**Returns:**
|
|
38
|
-
`Promise<
|
|
38
|
+
`Promise<TideTokenClaims | null>`
|
|
39
39
|
|
|
40
40
|
* **Success:** Decoded token payload when all checks pass.
|
|
41
41
|
* **Failure:** `null` if verification fails or the user lacks the required role(s).
|
|
@@ -48,13 +48,13 @@ Internally, `verifyTideCloakToken` uses the [jose](https://github.com/panva/jose
|
|
|
48
48
|
2. Construct the correct issuer URL from `config['auth-server-url']` and `config.realm`.
|
|
49
49
|
3. Choose between a local JWK Set (`config.jwk.keys`) or fetch the JWK Set remotely from Tidecloak.
|
|
50
50
|
4. Verify the token's signature against a **pinned algorithm allowlist** (`ES256`, `ES384`, `ES512`, `EdDSA` by default), the `issuer`, and the standard time claims (`exp`/`nbf`) with a small `clockTolerance`.
|
|
51
|
-
5. Verify the `azp` (authorized party) against `config.resource
|
|
51
|
+
5. Verify the `azp` (authorized party) against `config.resource`, **only when `resource` is configured**.
|
|
52
52
|
6. Extract realm (`payload.realm_access.roles`) and client (`payload.resource_access[resource].roles`) roles.
|
|
53
53
|
7. Check for at least one matching role if `allowedRoles` is specified.
|
|
54
54
|
|
|
55
55
|
On any failure, it logs the error message to the console and returns `null`.
|
|
56
56
|
|
|
57
|
-
> **Note:** the algorithm allowlist closes algorithm-confusion attacks
|
|
57
|
+
> **Note:** the algorithm allowlist closes algorithm-confusion attacks. Without it, `jose` would accept any algorithm a key in the set can validate. A `null` result collapses both invalid tokens and infrastructure failures (e.g. an unreachable remote JWKS endpoint), so treat `null` as "not authorized" and monitor your JWKS reachability separately.
|
|
58
58
|
|
|
59
59
|
### Optional config fields
|
|
60
60
|
|
|
@@ -78,7 +78,7 @@ You can tune verification by adding these optional fields to the `config` object
|
|
|
78
78
|
import express from 'express';
|
|
79
79
|
import cookieParser from 'cookie-parser';
|
|
80
80
|
import { verifyTideCloakToken } from '@tidecloak/verify';
|
|
81
|
-
import config from './
|
|
81
|
+
import config from './tidecloak.json' with { type: 'json' };
|
|
82
82
|
|
|
83
83
|
const app = express();
|
|
84
84
|
app.use(cookieParser());
|
|
@@ -102,7 +102,7 @@ app.listen(3000, () => console.log('Server running on port 3000'));
|
|
|
102
102
|
const express = require('express');
|
|
103
103
|
const cookieParser = require('cookie-parser');
|
|
104
104
|
const { verifyTideCloakToken } = require('@tidecloak/verify');
|
|
105
|
-
const config = require('./
|
|
105
|
+
const config = require('./tidecloak.json');
|
|
106
106
|
|
|
107
107
|
const app = express();
|
|
108
108
|
app.use(cookieParser());
|
|
@@ -124,7 +124,7 @@ app.listen(3000, () => console.log('Server running on port 3000'));
|
|
|
124
124
|
// pages/secure.js (Next.js Pages Router)
|
|
125
125
|
import React from 'react';
|
|
126
126
|
import { verifyTideCloakToken } from '@tidecloak/verify';
|
|
127
|
-
import config from '../
|
|
127
|
+
import config from '../tidecloak.json';
|
|
128
128
|
|
|
129
129
|
export async function getServerSideProps({ req }) {
|
|
130
130
|
const token = req.cookies.kcToken || req.headers.authorization?.split(' ')[1] || '';
|
|
@@ -146,7 +146,7 @@ export default function SecurePage({ user }) {
|
|
|
146
146
|
// pages/api/secure.ts
|
|
147
147
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
148
148
|
import { verifyTideCloakToken } from '@tidecloak/verify';
|
|
149
|
-
import config from '../../
|
|
149
|
+
import config from '../../tidecloak.json';
|
|
150
150
|
|
|
151
151
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
152
152
|
const token = req.cookies.kcToken || req.headers.authorization?.split(' ')[1] || '';
|
|
@@ -164,7 +164,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|
|
164
164
|
// app/api/secure/route.ts
|
|
165
165
|
import { NextRequest, NextResponse } from 'next/server';
|
|
166
166
|
import { verifyTideCloakToken } from '@tidecloak/verify';
|
|
167
|
-
import config from '../../../
|
|
167
|
+
import config from '../../../tidecloak.json';
|
|
168
168
|
|
|
169
169
|
export async function GET(req: NextRequest) {
|
|
170
170
|
const token = req.cookies.get('kcToken')?.value || '';
|
|
@@ -180,13 +180,17 @@ export async function GET(req: NextRequest) {
|
|
|
180
180
|
|
|
181
181
|
## TypeScript Definitions
|
|
182
182
|
|
|
183
|
+
The fields `verifyTideCloakToken` reads from `config`:
|
|
184
|
+
|
|
183
185
|
```ts
|
|
184
186
|
interface TidecloakConfig {
|
|
185
187
|
realm: string;
|
|
186
188
|
'auth-server-url': string;
|
|
187
189
|
resource?: string;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
+
'public-client'?: boolean;
|
|
191
|
+
'confidential-port'?: number;
|
|
192
|
+
'ssl-required'?: string;
|
|
193
|
+
/** Local JWKS. When absent, keys are fetched from the realm's certs endpoint. */
|
|
190
194
|
jwk?: { keys: Array<{ kid: string; kty: string; alg?: string; use?: string; x?: string; crv?: string; n?: string; e?: string }> };
|
|
191
195
|
/** Allowed JWS signature algorithms. Default: ['ES256','ES384','ES512','EdDSA']. */
|
|
192
196
|
tokenSignatureAlgorithms?: string[];
|
|
@@ -195,11 +199,21 @@ interface TidecloakConfig {
|
|
|
195
199
|
[key: string]: unknown;
|
|
196
200
|
}
|
|
197
201
|
|
|
202
|
+
type TideTokenClaims = Record<string, unknown> & {
|
|
203
|
+
tideuserkey?: string;
|
|
204
|
+
vuid?: string;
|
|
205
|
+
sub?: string;
|
|
206
|
+
iss?: string;
|
|
207
|
+
azp?: string;
|
|
208
|
+
realm_access?: { roles?: string[] };
|
|
209
|
+
resource_access?: Record<string, { roles?: string[] }>;
|
|
210
|
+
};
|
|
211
|
+
|
|
198
212
|
export declare function verifyTideCloakToken(
|
|
199
|
-
config:
|
|
213
|
+
config: object,
|
|
200
214
|
token: string,
|
|
201
215
|
allowedRoles?: string[]
|
|
202
|
-
): Promise<
|
|
216
|
+
): Promise<TideTokenClaims | null>;
|
|
203
217
|
```
|
|
204
218
|
|
|
205
219
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tidecloak/verify",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.33",
|
|
4
4
|
"description": "A lightweight utility for server-side verification of TideCloak-issued JSON Web Tokens (JWTs).",
|
|
5
5
|
"main": "./dist/cjs/TideJWT.js",
|
|
6
6
|
"module": "./dist/esm/TideJWT.js",
|