@tdacorp/identity-client 0.2.1 → 0.2.2

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.
@@ -306,6 +306,12 @@ async function verifyIdToken(idToken, options) {
306
306
  const result = await verifyAgainstIssuer(idToken, options);
307
307
  if ("errors" in result) return { success: false, errors: result.errors };
308
308
  const { payload } = result;
309
+ if ("token_use" in payload) {
310
+ return {
311
+ success: false,
312
+ errors: [{ code: "wrong-token-type", message: "Token has a token_use claim; an id_token never carries one. This is an access token, not an id_token." }]
313
+ };
314
+ }
309
315
  if (typeof payload.sub !== "string") {
310
316
  return { success: false, errors: [{ code: "malformed-claims", message: "id_token has no sub claim" }] };
311
317
  }
@@ -315,6 +321,12 @@ async function verifyAccessToken(accessToken, options) {
315
321
  const result = await verifyAgainstIssuer(accessToken, options);
316
322
  if ("errors" in result) return { success: false, errors: result.errors };
317
323
  const { payload } = result;
324
+ if (payload.token_use !== "oauth_access") {
325
+ return {
326
+ success: false,
327
+ errors: [{ code: "wrong-token-type", message: 'Token is missing token_use: "oauth_access". This is not an access token (likely an id_token).' }]
328
+ };
329
+ }
318
330
  const claims = payload;
319
331
  const roles = "roles" in claims ? claims.roles : void 0;
320
332
  if (typeof payload.sub === "string") {
package/dist/index.cjs CHANGED
@@ -343,6 +343,12 @@ async function verifyIdToken(idToken, options) {
343
343
  const result = await verifyAgainstIssuer(idToken, options);
344
344
  if ("errors" in result) return { success: false, errors: result.errors };
345
345
  const { payload } = result;
346
+ if ("token_use" in payload) {
347
+ return {
348
+ success: false,
349
+ errors: [{ code: "wrong-token-type", message: "Token has a token_use claim; an id_token never carries one. This is an access token, not an id_token." }]
350
+ };
351
+ }
346
352
  if (typeof payload.sub !== "string") {
347
353
  return { success: false, errors: [{ code: "malformed-claims", message: "id_token has no sub claim" }] };
348
354
  }
@@ -352,6 +358,12 @@ async function verifyAccessToken(accessToken, options) {
352
358
  const result = await verifyAgainstIssuer(accessToken, options);
353
359
  if ("errors" in result) return { success: false, errors: result.errors };
354
360
  const { payload } = result;
361
+ if (payload.token_use !== "oauth_access") {
362
+ return {
363
+ success: false,
364
+ errors: [{ code: "wrong-token-type", message: 'Token is missing token_use: "oauth_access". This is not an access token (likely an id_token).' }]
365
+ };
366
+ }
355
367
  const claims = payload;
356
368
  const roles = "roles" in claims ? claims.roles : void 0;
357
369
  if (typeof payload.sub === "string") {
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRemoteJWKSet } from 'jose';
2
- export { A as AuthorizationCodeExchangeOptions, C as CLOCK_SKEW_TOLERANCE_SECONDS, a as ClientCredentialsGrantOptions, I as IdTokenClaims, R as RefreshTokensOptions, T as TokenEndpointAuthMethod, b as TokenRefreshOutcome, c as TokenRequestError, d as TokenSet, e as TokenVerificationError, f as TokenVerificationErrorCode, V as VerificationResult, g as VerifiedAccessToken, h as VerifyTokenOptions, i as clientCredentialsGrant, j as exchangeAuthorizationCode, r as refreshTokens, v as verifyAccessToken, k as verifyIdToken } from './verify-C1Ga6JbS.cjs';
2
+ export { A as AuthorizationCodeExchangeOptions, C as CLOCK_SKEW_TOLERANCE_SECONDS, a as ClientCredentialsGrantOptions, I as IdTokenClaims, R as RefreshTokensOptions, T as TokenEndpointAuthMethod, b as TokenRefreshOutcome, c as TokenRequestError, d as TokenSet, e as TokenVerificationError, f as TokenVerificationErrorCode, V as VerificationResult, g as VerifiedAccessToken, h as VerifyTokenOptions, i as clientCredentialsGrant, j as exchangeAuthorizationCode, r as refreshTokens, v as verifyAccessToken, k as verifyIdToken } from './verify-ggSzUrdC.cjs';
3
3
  import '@tdacorp/identity-authz';
4
4
 
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRemoteJWKSet } from 'jose';
2
- export { A as AuthorizationCodeExchangeOptions, C as CLOCK_SKEW_TOLERANCE_SECONDS, a as ClientCredentialsGrantOptions, I as IdTokenClaims, R as RefreshTokensOptions, T as TokenEndpointAuthMethod, b as TokenRefreshOutcome, c as TokenRequestError, d as TokenSet, e as TokenVerificationError, f as TokenVerificationErrorCode, V as VerificationResult, g as VerifiedAccessToken, h as VerifyTokenOptions, i as clientCredentialsGrant, j as exchangeAuthorizationCode, r as refreshTokens, v as verifyAccessToken, k as verifyIdToken } from './verify-C1Ga6JbS.js';
2
+ export { A as AuthorizationCodeExchangeOptions, C as CLOCK_SKEW_TOLERANCE_SECONDS, a as ClientCredentialsGrantOptions, I as IdTokenClaims, R as RefreshTokensOptions, T as TokenEndpointAuthMethod, b as TokenRefreshOutcome, c as TokenRequestError, d as TokenSet, e as TokenVerificationError, f as TokenVerificationErrorCode, V as VerificationResult, g as VerifiedAccessToken, h as VerifyTokenOptions, i as clientCredentialsGrant, j as exchangeAuthorizationCode, r as refreshTokens, v as verifyAccessToken, k as verifyIdToken } from './verify-ggSzUrdC.js';
3
3
  import '@tdacorp/identity-authz';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  refreshTokens,
12
12
  verifyAccessToken,
13
13
  verifyIdToken
14
- } from "./chunk-S5WGUOJA.js";
14
+ } from "./chunk-TTFIPEZ3.js";
15
15
  export {
16
16
  CLOCK_SKEW_TOLERANCE_SECONDS,
17
17
  TokenRequestError,
package/dist/next.cjs CHANGED
@@ -280,6 +280,12 @@ async function verifyIdToken(idToken, options) {
280
280
  const result = await verifyAgainstIssuer(idToken, options);
281
281
  if ("errors" in result) return { success: false, errors: result.errors };
282
282
  const { payload } = result;
283
+ if ("token_use" in payload) {
284
+ return {
285
+ success: false,
286
+ errors: [{ code: "wrong-token-type", message: "Token has a token_use claim; an id_token never carries one. This is an access token, not an id_token." }]
287
+ };
288
+ }
283
289
  if (typeof payload.sub !== "string") {
284
290
  return { success: false, errors: [{ code: "malformed-claims", message: "id_token has no sub claim" }] };
285
291
  }
package/dist/next.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NextResponse, NextRequest } from 'next/server';
2
- import { d as TokenSet, I as IdTokenClaims } from './verify-C1Ga6JbS.cjs';
2
+ import { d as TokenSet, I as IdTokenClaims } from './verify-ggSzUrdC.cjs';
3
3
  import { SealSecret } from './sealed.cjs';
4
4
  import '@tdacorp/identity-authz';
5
5
  import 'jose';
package/dist/next.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NextResponse, NextRequest } from 'next/server';
2
- import { d as TokenSet, I as IdTokenClaims } from './verify-C1Ga6JbS.js';
2
+ import { d as TokenSet, I as IdTokenClaims } from './verify-ggSzUrdC.js';
3
3
  import { SealSecret } from './sealed.js';
4
4
  import '@tdacorp/identity-authz';
5
5
  import 'jose';
package/dist/next.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  generateCodeVerifier,
6
6
  generateState,
7
7
  verifyIdToken
8
- } from "./chunk-S5WGUOJA.js";
8
+ } from "./chunk-TTFIPEZ3.js";
9
9
  import {
10
10
  seal,
11
11
  unseal
@@ -246,8 +246,14 @@ declare const CLOCK_SKEW_TOLERANCE_SECONDS = 60;
246
246
  * - `'malformed-token'`: the token is not a well-formed JWT at all.
247
247
  * - `'jwks-unavailable'`: the issuer's discovery document or JWKS could not
248
248
  * be fetched -- infrastructure, not a verdict on the token.
249
+ * - `'wrong-token-type'`: the token verified (right issuer, right audience,
250
+ * right signature) but is the OTHER kind of token this server mints for a
251
+ * login -- an id_token presented to `verifyAccessToken`, or an access
252
+ * token presented to `verifyIdToken`. The two share `iss`/`sub`/`aud`/`azp`
253
+ * and are signed by the same key, so nothing else here would catch this;
254
+ * see `token_use` on `IdentityTokenPayload`.
249
255
  */
250
- type TokenVerificationErrorCode = 'expired' | 'invalid-signature' | 'invalid-issuer' | 'invalid-audience' | 'unauthorized-party' | 'malformed-claims' | 'malformed-token' | 'jwks-unavailable';
256
+ type TokenVerificationErrorCode = 'expired' | 'invalid-signature' | 'invalid-issuer' | 'invalid-audience' | 'unauthorized-party' | 'malformed-claims' | 'malformed-token' | 'jwks-unavailable' | 'wrong-token-type';
251
257
  /** One verification failure: a stable `code` to branch on, plus a
252
258
  * human-readable `message` for logs. `verifyIdToken`/`verifyAccessToken`
253
259
  * return a list of these rather than throwing -- see `VerificationResult`. */
@@ -246,8 +246,14 @@ declare const CLOCK_SKEW_TOLERANCE_SECONDS = 60;
246
246
  * - `'malformed-token'`: the token is not a well-formed JWT at all.
247
247
  * - `'jwks-unavailable'`: the issuer's discovery document or JWKS could not
248
248
  * be fetched -- infrastructure, not a verdict on the token.
249
+ * - `'wrong-token-type'`: the token verified (right issuer, right audience,
250
+ * right signature) but is the OTHER kind of token this server mints for a
251
+ * login -- an id_token presented to `verifyAccessToken`, or an access
252
+ * token presented to `verifyIdToken`. The two share `iss`/`sub`/`aud`/`azp`
253
+ * and are signed by the same key, so nothing else here would catch this;
254
+ * see `token_use` on `IdentityTokenPayload`.
249
255
  */
250
- type TokenVerificationErrorCode = 'expired' | 'invalid-signature' | 'invalid-issuer' | 'invalid-audience' | 'unauthorized-party' | 'malformed-claims' | 'malformed-token' | 'jwks-unavailable';
256
+ type TokenVerificationErrorCode = 'expired' | 'invalid-signature' | 'invalid-issuer' | 'invalid-audience' | 'unauthorized-party' | 'malformed-claims' | 'malformed-token' | 'jwks-unavailable' | 'wrong-token-type';
251
257
  /** One verification failure: a stable `code` to branch on, plus a
252
258
  * human-readable `message` for logs. `verifyIdToken`/`verifyAccessToken`
253
259
  * return a list of these rather than throwing -- see `VerificationResult`. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tdacorp/identity-client",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "OIDC relying-party client for TDACorp Identity: discovery, PKCE, token exchange, token verification and Next.js route helpers.",
5
5
  "license": "MIT",
6
6
  "bugs": {