From afc2a8a9171bae7e30ed7c7d9bd094d8cbd49b80 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Thu, 25 Apr 2024 02:19:23 +0200 Subject: [PATCH] fix: issuance and expiration sometimes used milliseconds instead of seconds --- .../callback-example/lib/__tests__/issuerCallback.spec.ts | 2 +- .../client/lib/__tests__/ProofOfPossessionBuilder.spec.ts | 2 +- packages/client/lib/__tests__/SdJwt.spec.ts | 2 +- packages/client/lib/functions/ProofUtil.ts | 4 ++-- packages/issuer-rest/lib/IssuerTokenEndpoint.ts | 4 ++-- packages/issuer-rest/lib/__tests__/ClientIssuerIT.spec.ts | 2 +- packages/issuer/lib/VcIssuer.ts | 2 +- packages/issuer/lib/__tests__/VcIssuer.spec.ts | 6 +++--- packages/issuer/lib/tokens/index.ts | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/callback-example/lib/__tests__/issuerCallback.spec.ts b/packages/callback-example/lib/__tests__/issuerCallback.spec.ts index 5a27a7bf..335a9999 100644 --- a/packages/callback-example/lib/__tests__/issuerCallback.spec.ts +++ b/packages/callback-example/lib/__tests__/issuerCallback.spec.ts @@ -37,7 +37,7 @@ async function proofOfPossessionCallbackFunction(args: Jwt, kid?: string): Promi } return await new jose.SignJWT({ ...args.payload }) .setProtectedHeader({ ...args.header }) - .setIssuedAt(+new Date()) + .setIssuedAt(args.payload.iat ?? Math.round(+new Date()/1000)) .setIssuer(kid) .setAudience(args.payload.aud) .setExpirationTime('2h') diff --git a/packages/client/lib/__tests__/ProofOfPossessionBuilder.spec.ts b/packages/client/lib/__tests__/ProofOfPossessionBuilder.spec.ts index a4ef65d3..4c614070 100644 --- a/packages/client/lib/__tests__/ProofOfPossessionBuilder.spec.ts +++ b/packages/client/lib/__tests__/ProofOfPossessionBuilder.spec.ts @@ -9,7 +9,7 @@ import { IDENTIPROOF_ISSUER_URL } from './MetadataMocks'; const jwt: Jwt = { header: { alg: Alg.ES256, kid: 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1', typ: 'jwt' }, - payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now() }, + payload: { iss: 'sphereon:wallet', nonce: 'tZignsnFbp', jti: 'tZignsnFbp223', aud: IDENTIPROOF_ISSUER_URL, iat: Date.now()/1000 }, }; const kid = 'did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1'; diff --git a/packages/client/lib/__tests__/SdJwt.spec.ts b/packages/client/lib/__tests__/SdJwt.spec.ts index 01629035..4ea99bf5 100644 --- a/packages/client/lib/__tests__/SdJwt.spec.ts +++ b/packages/client/lib/__tests__/SdJwt.spec.ts @@ -43,7 +43,7 @@ const vcIssuer = new VcIssuerBuilder() }, payload: { aud: issuerMetadata.credential_issuer, - iat: +new Date(), + iat: +new Date()/1000, nonce: 'a-c-nonce', }, }, diff --git a/packages/client/lib/functions/ProofUtil.ts b/packages/client/lib/functions/ProofUtil.ts index cbfed4be..fb10d531 100644 --- a/packages/client/lib/functions/ProofUtil.ts +++ b/packages/client/lib/functions/ProofUtil.ts @@ -94,8 +94,8 @@ const createJWT = (jwtProps?: JwtProps, existingJwt?: Jwt): Jwt => { const now = +new Date(); const jwtPayload: Partial = { aud, - iat: jwt.payload?.iat ? jwt.payload.iat : now / 1000 - 60, // Let's ensure we subtract 60 seconds for potential time offsets - exp: jwt.payload?.exp ? jwt.payload.exp : now / 1000 + 10 * 60, + iat: jwt.payload?.iat ?? Math.round(now / 1000 - 60), // Let's ensure we subtract 60 seconds for potential time offsets + exp: jwt.payload?.exp ?? Math.round(now / 1000 + 10 * 60), nonce, ...(iss ? { iss } : {}), ...(jti ? { jti } : {}), diff --git a/packages/issuer-rest/lib/IssuerTokenEndpoint.ts b/packages/issuer-rest/lib/IssuerTokenEndpoint.ts index 6274d2c2..81bd3047 100644 --- a/packages/issuer-rest/lib/IssuerTokenEndpoint.ts +++ b/packages/issuer-rest/lib/IssuerTokenEndpoint.ts @@ -14,10 +14,10 @@ import { v4 } from 'uuid' * @param interval */ export const handleTokenRequest = ({ - tokenExpiresIn, + tokenExpiresIn, // expiration in seconds accessTokenSignerCallback, accessTokenIssuer, - cNonceExpiresIn, + cNonceExpiresIn, // expiration in seconds issuer, interval, }: Required> & { diff --git a/packages/issuer-rest/lib/__tests__/ClientIssuerIT.spec.ts b/packages/issuer-rest/lib/__tests__/ClientIssuerIT.spec.ts index 034b7a2b..c9fb88ad 100644 --- a/packages/issuer-rest/lib/__tests__/ClientIssuerIT.spec.ts +++ b/packages/issuer-rest/lib/__tests__/ClientIssuerIT.spec.ts @@ -314,7 +314,7 @@ describe('VcIssuer', () => { async function proofOfPossessionCallbackFunction(args: Jwt, kid?: string): Promise { return await new jose.SignJWT({ ...args.payload }) .setProtectedHeader({ ...args.header }) - .setIssuedAt(+new Date()) + .setIssuedAt(args.payload.iat ?? Math.round(+new Date()/1000)) .setIssuer(kid!) .setAudience(args.payload.aud!) .setExpirationTime('2h') diff --git a/packages/issuer/lib/VcIssuer.ts b/packages/issuer/lib/VcIssuer.ts index ded66478..acbc3ceb 100644 --- a/packages/issuer/lib/VcIssuer.ts +++ b/packages/issuer/lib/VcIssuer.ts @@ -519,7 +519,7 @@ export class VcIssuer { } if (!iat) { throw new Error(IAT_ERROR) - } else if (iat > (createdAt/1000 + tokenExpiresIn)) { + } else if (iat > Math.round(createdAt/1000) + tokenExpiresIn) { // createdAt is in milliseconds whilst iat and tokenExpiresIn are in seconds throw new Error(IAT_ERROR) } diff --git a/packages/issuer/lib/__tests__/VcIssuer.spec.ts b/packages/issuer/lib/__tests__/VcIssuer.spec.ts index 62cc8068..3f5134cb 100644 --- a/packages/issuer/lib/__tests__/VcIssuer.spec.ts +++ b/packages/issuer/lib/__tests__/VcIssuer.spec.ts @@ -284,7 +284,7 @@ describe('VcIssuer', () => { }, payload: { aud: IDENTIPROOF_ISSUER_URL, - iat: +new Date(), + iat: +new Date()/1000, nonce: 'test-nonce', }, }, @@ -322,7 +322,7 @@ describe('VcIssuer', () => { }, payload: { aud: IDENTIPROOF_ISSUER_URL, - iat: +new Date(), + iat: +new Date()/1000, nonce: 'test-nonce', }, }, @@ -405,7 +405,7 @@ describe('VcIssuer', () => { }, payload: { aud: IDENTIPROOF_ISSUER_URL, - iat: +new Date(), + iat: +new Date()/1000, nonce: 'test-nonce', }, }, diff --git a/packages/issuer/lib/tokens/index.ts b/packages/issuer/lib/tokens/index.ts index 4a51584e..a051a3bc 100644 --- a/packages/issuer/lib/tokens/index.ts +++ b/packages/issuer/lib/tokens/index.ts @@ -134,8 +134,8 @@ export const createAccessTokenResponse = async ( credentialOfferSessions: IStateManager cNonces: IStateManager cNonce?: string - cNonceExpiresIn?: number - tokenExpiresIn: number + cNonceExpiresIn?: number // expiration in seconds + tokenExpiresIn: number // expiration in seconds // preAuthorizedCodeExpirationDuration?: number accessTokenSignerCallback: JWTSignerCallback accessTokenIssuer: string