Skip to content

Commit 6effa4d

Browse files
committed
feat(types): allow generics to aid in CryptoKey or KeyObject narrowing of KeyLike
1 parent 20610a9 commit 6effa4d

File tree

15 files changed

+79
-53
lines changed

15 files changed

+79
-53
lines changed

src/jwe/compact/decrypt.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ export async function compactDecrypt(
4747
* @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
4848
* @param options JWE Decryption options.
4949
*/
50-
export async function compactDecrypt(
50+
export async function compactDecrypt<T extends KeyLike = KeyLike>(
5151
jwe: string | Uint8Array,
5252
getKey: CompactDecryptGetKey,
5353
options?: DecryptOptions,
54-
): Promise<CompactDecryptResult & ResolvedKey>
54+
): Promise<CompactDecryptResult & ResolvedKey<T>>
5555
export async function compactDecrypt(
5656
jwe: string | Uint8Array,
5757
key: KeyLike | Uint8Array | CompactDecryptGetKey,

src/jwe/flattened/decrypt.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ export function flattenedDecrypt(
6666
* @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
6767
* @param options JWE Decryption options.
6868
*/
69-
export function flattenedDecrypt(
69+
export function flattenedDecrypt<T extends KeyLike = KeyLike>(
7070
jwe: FlattenedJWE,
7171
getKey: FlattenedDecryptGetKey,
7272
options?: DecryptOptions,
73-
): Promise<FlattenedDecryptResult & ResolvedKey>
73+
): Promise<FlattenedDecryptResult & ResolvedKey<T>>
7474
export async function flattenedDecrypt(
7575
jwe: FlattenedJWE,
7676
key: KeyLike | Uint8Array | FlattenedDecryptGetKey,

src/jwe/general/decrypt.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ export function generalDecrypt(
6161
* @param getKey Function resolving Private Key or Secret to decrypt the JWE with.
6262
* @param options JWE Decryption options.
6363
*/
64-
export function generalDecrypt(
64+
export function generalDecrypt<T extends KeyLike = KeyLike>(
6565
jwe: GeneralJWE,
6666
getKey: GeneralDecryptGetKey,
6767
options?: DecryptOptions,
68-
): Promise<GeneralDecryptResult & ResolvedKey>
68+
): Promise<GeneralDecryptResult & ResolvedKey<T>>
6969
export async function generalDecrypt(
7070
jwe: GeneralJWE,
7171
key: KeyLike | Uint8Array | GeneralDecryptGetKey,

src/jwk/embedded.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ import { JWSInvalid } from '../util/errors.js'
2424
* console.log(payload)
2525
* ```
2626
*/
27-
export async function EmbeddedJWK(
28-
): Promise<KeyLike> {
27+
export async function EmbeddedJWK<T extends KeyLike = KeyLike>(
2928
protectedHeader?: JWSHeaderParameters,
3029
token?: FlattenedJWSInput,
30+
): Promise<T> {
3131
const joseHeader = {
3232
...protectedHeader,
3333
...token?.header,
@@ -36,7 +36,7 @@ export async function EmbeddedJWK(
3636
throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a JSON object')
3737
}
3838

39-
const key = await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg!, true)
39+
const key = await importJWK<T>({ ...joseHeader.jwk, ext: true }, joseHeader.alg!, true)
4040

4141
if (key instanceof Uint8Array || key.type !== 'public') {
4242
throw new JWSInvalid('"jwk" (JSON Web Key) Header Parameter must be a public key')

src/jwks/local.ts

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ function getKtyFromAlg(alg: unknown) {
2828
}
2929
}
3030

31-
interface Cache {
32-
[alg: string]: KeyLike
31+
interface Cache<T extends KeyLike = KeyLike> {
32+
[alg: string]: T
3333
}
3434

3535
/** @private */
@@ -59,10 +59,10 @@ function clone<T>(obj: T): T {
5959
}
6060

6161
/** @private */
62-
export class LocalJWKSet {
62+
export class LocalJWKSet<T extends KeyLike = KeyLike> {
6363
protected _jwks?: JSONWebKeySet
6464

65-
private _cached: WeakMap<JWK, Cache> = new WeakMap()
65+
private _cached: WeakMap<JWK, Cache<T>> = new WeakMap()
6666

6767
constructor(jwks: unknown) {
6868
if (!isJWKSLike(jwks)) {
@@ -72,7 +72,7 @@ export class LocalJWKSet {
7272
this._jwks = clone<JSONWebKeySet>(jwks)
7373
}
7474

75-
async getKey(protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput): Promise<KeyLike> {
75+
async getKey(protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput): Promise<T> {
7676
const { alg, kid } = { ...protectedHeader, ...token?.header }
7777
const kty = getKtyFromAlg(alg)
7878

@@ -137,7 +137,7 @@ export class LocalJWKSet {
137137
error[Symbol.asyncIterator] = async function* () {
138138
for (const jwk of candidates) {
139139
try {
140-
yield await importWithAlgCache(_cached, jwk, alg!)
140+
yield await importWithAlgCache<T>(_cached, jwk, alg!)
141141
} catch {
142142
continue
143143
}
@@ -147,20 +147,24 @@ export class LocalJWKSet {
147147
throw error
148148
}
149149

150-
return importWithAlgCache(this._cached, jwk, alg!)
150+
return importWithAlgCache<T>(this._cached, jwk, alg!)
151151
}
152152
}
153153

154-
async function importWithAlgCache(cache: WeakMap<JWK, Cache>, jwk: JWK, alg: string) {
154+
async function importWithAlgCache<T extends KeyLike = KeyLike>(
155+
cache: WeakMap<JWK, Cache<T>>,
156+
jwk: JWK,
157+
alg: string,
158+
) {
155159
const cached = cache.get(jwk) || cache.set(jwk, {}).get(jwk)!
156160
if (cached[alg] === undefined) {
157-
const keyObject = <KeyLike>await importJWK({ ...jwk, ext: true }, alg)
161+
const key = await importJWK<T>({ ...jwk, ext: true }, alg)
158162

159-
if (keyObject.type !== 'public') {
163+
if (key instanceof Uint8Array || key.type !== 'public') {
160164
throw new JWKSInvalid('JSON Web Key Set members must be public keys')
161165
}
162166

163-
cached[alg] = keyObject
167+
cached[alg] = key
164168
}
165169

166170
return cached[alg]
@@ -240,6 +244,12 @@ async function importWithAlgCache(cache: WeakMap<JWK, Cache>, jwk: JWK, alg: str
240244
*
241245
* @param jwks JSON Web Key Set formatted object.
242246
*/
243-
export function createLocalJWKSet(jwks: JSONWebKeySet) {
244-
return LocalJWKSet.prototype.getKey.bind(new LocalJWKSet(jwks))
247+
export function createLocalJWKSet<T extends KeyLike = KeyLike>(jwks: JSONWebKeySet) {
248+
const set = new LocalJWKSet<T>(jwks)
249+
return async function (
250+
protectedHeader?: JWSHeaderParameters,
251+
token?: FlattenedJWSInput,
252+
): Promise<T> {
253+
return set.getKey(protectedHeader, token)
254+
}
245255
}

src/jwks/remote.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export interface RemoteJWKSetOptions {
4040
headers?: Record<string, string>
4141
}
4242

43-
class RemoteJWKSet extends LocalJWKSet {
43+
class RemoteJWKSet<T extends KeyLike = KeyLike> extends LocalJWKSet<T> {
4444
private _url: URL
4545

4646
private _timeoutDuration: number
@@ -84,7 +84,7 @@ class RemoteJWKSet extends LocalJWKSet {
8484
: false
8585
}
8686

87-
async getKey(protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput): Promise<KeyLike> {
87+
async getKey(protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput): Promise<T> {
8888
if (!this._jwks || !this.fresh()) {
8989
await this.reload()
9090
}
@@ -199,6 +199,15 @@ class RemoteJWKSet extends LocalJWKSet {
199199
* @param url URL to fetch the JSON Web Key Set from.
200200
* @param options Options for the remote JSON Web Key Set.
201201
*/
202-
export function createRemoteJWKSet(url: URL, options?: RemoteJWKSetOptions) {
203-
return RemoteJWKSet.prototype.getKey.bind(new RemoteJWKSet(url, options))
202+
export function createRemoteJWKSet<T extends KeyLike = KeyLike>(
203+
url: URL,
204+
options?: RemoteJWKSetOptions,
205+
) {
206+
const set = new RemoteJWKSet<T>(url, options)
207+
return async function (
208+
protectedHeader?: JWSHeaderParameters,
209+
token?: FlattenedJWSInput,
210+
): Promise<T> {
211+
return set.getKey(protectedHeader, token)
212+
}
204213
}

src/jws/compact/verify.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ export function compactVerify(
5151
* @param getKey Function resolving a key to verify the JWS with.
5252
* @param options JWS Verify options.
5353
*/
54-
export function compactVerify(
54+
export function compactVerify<T extends KeyLike = KeyLike>(
5555
jws: string | Uint8Array,
5656
getKey: CompactVerifyGetKey,
5757
options?: VerifyOptions,
58-
): Promise<CompactVerifyResult & ResolvedKey>
58+
): Promise<CompactVerifyResult & ResolvedKey<T>>
5959
export async function compactVerify(
6060
jws: string | Uint8Array,
6161
key: KeyLike | Uint8Array | CompactVerifyGetKey,

src/jws/flattened/verify.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,11 @@ export function flattenedVerify(
6464
* @param getKey Function resolving a key to verify the JWS with.
6565
* @param options JWS Verify options.
6666
*/
67-
export function flattenedVerify(
67+
export function flattenedVerify<T extends KeyLike = KeyLike>(
6868
jws: FlattenedJWSInput,
6969
getKey: FlattenedVerifyGetKey,
7070
options?: VerifyOptions,
71-
): Promise<FlattenedVerifyResult & ResolvedKey>
71+
): Promise<FlattenedVerifyResult & ResolvedKey<T>>
7272
export async function flattenedVerify(
7373
jws: FlattenedJWSInput,
7474
key: KeyLike | Uint8Array | FlattenedVerifyGetKey,

src/jws/general/verify.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ export function generalVerify(
6060
* @param getKey Function resolving a key to verify the JWS with.
6161
* @param options JWS Verify options.
6262
*/
63-
export function generalVerify(
63+
export function generalVerify<T extends KeyLike = KeyLike>(
6464
jws: GeneralJWSInput,
6565
getKey: GeneralVerifyGetKey,
6666
options?: VerifyOptions,
67-
): Promise<GeneralVerifyResult & ResolvedKey>
67+
): Promise<GeneralVerifyResult & ResolvedKey<T>>
6868
export async function generalVerify(
6969
jws: GeneralJWSInput,
7070
key: KeyLike | Uint8Array | GeneralVerifyGetKey,

src/jwt/decrypt.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ export async function jwtDecrypt(
5656
* @param getKey Function resolving Private Key or Secret to decrypt and verify the JWT with.
5757
* @param options JWT Decryption and JWT Claims Set validation options.
5858
*/
59-
export async function jwtDecrypt(
59+
export async function jwtDecrypt<T extends KeyLike = KeyLike>(
6060
jwt: string | Uint8Array,
6161
getKey: JWTDecryptGetKey,
6262
options?: JWTDecryptOptions,
63-
): Promise<JWTDecryptResult & ResolvedKey>
63+
): Promise<JWTDecryptResult & ResolvedKey<T>>
6464
export async function jwtDecrypt(
6565
jwt: string | Uint8Array,
6666
key: KeyLike | Uint8Array | JWTDecryptGetKey,

0 commit comments

Comments
 (0)