Skip to content

Commit

Permalink
feat: improve key input type errors, remove dependency on @types/node
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Oct 6, 2021
1 parent 94815a9 commit a13eb04
Show file tree
Hide file tree
Showing 52 changed files with 388 additions and 229 deletions.
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,8 @@
"dist/**/*.js",
"dist/types/**/*.d.ts",
"!dist/node/webcrypto/**/*",
"!dist/types/**/*.i.d.ts",
"!dist/types/runtime/*",
"!dist/types/lib/*",
"dist/types/lib/jwt_producer.d.ts"
"!dist/types/lib/*"
],
"scripts": {
"build": "tsc",
Expand All @@ -238,7 +236,7 @@
"build-fast:node-webcrypto-cjs": "npm run-script runtime-node-webcrypto && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --platform=node --target=esnext --outdir=dist/node/webcrypto/cjs --format=cjs",
"build-fast:node-webcrypto-esm": "npm run-script runtime-node-webcrypto && npm run-script -s esbuild-find | xargs -0 esbuild --log-level=warning --platform=node --target=esnext --outdir=dist/node/webcrypto/esm --format=esm && echo '{\"type\": \"module\"}'> dist/node/webcrypto/esm/package.json",
"build:browser": "run-s runtime-browser 'build -- -p ./tsconfig/browser.json' && echo '{\"type\": \"module\"}'> dist/browser/package.json",
"build:deno": "npm run-script runtime-deno && find dist/deno -name '*.ts' -type f -print0 | xargs -0 sed -i '' -e \"s/@deno\\-expect\\-error/@ts-ignore/g\" -e \"s/\\.js'/.ts'/g\" -e \"s/\\.d'/.d.ts'/g\" && echo 'export type KeyObject = CryptoKey' > dist/deno/types.d.ts && tail -n +5 src/types.d.ts >> dist/deno/types.d.ts",
"build:deno": "npm run-script runtime-deno && find dist/deno -name '*.ts' -type f -print0 | xargs -0 sed -i '' -e \"s/@deno\\-expect\\-error/@ts-ignore/g\" -e \"s/\\.js'/.ts'/g\" -e \"s/\\.d'/.d.ts'/g\"",
"build:types": "npm run-script build -- -p ./tsconfig/types.json && cd src && find . -name '*.d.ts' -maxdepth 2 -type f -exec gcp --parents \"{}\" ../dist/types \\; && cd .. && node ./tools/strip-dts-comments && run-s -s types:find | xargs -0 sed -i '' -e \"s/\\.js'/'/g\" -e \"s/\\.d'/'/g\"",
"build:node-cjs": "run-s runtime-node 'build -- -p ./tsconfig/node-cjs.json'",
"build:node-esm": "run-s runtime-node 'build -- -p ./tsconfig/node-esm.json' && echo '{\"type\": \"module\"}'> dist/node/esm/package.json",
Expand All @@ -263,7 +261,7 @@
"runtime:refs": "run-s -s runtime:find | xargs -0 sed -i '' -e \"s/'\\.\\.\\//'\\.\\//g\" -e \"s/'\\.\\/\\.\\./'../g\"",
"test": "npm run-script test-cjs && ava",
"test-cloudflare-workers": "ava --timeout=5m --config ./test-cloudflare-workers.config.cjs",
"test-deno": "deno test --jobs --allow-net --allow-read test-deno",
"test-deno": "deno test --reload --jobs --allow-net --allow-read test-deno",
"test-browsers": "find test-browser -type f -name '*.js' -print0 | xargs -0 npx esbuild --log-level=warning --outdir=dist-browser-tests --bundle && karma start",
"test-cjs": "rm -rf test/cjs && find test -type f -name '*.mjs' -print0 | xargs -0 npx esbuild --log-level=warning --target=esnext --outdir=test/cjs --format=cjs",
"test-cryptokey": "CRYPTOKEY=true npm test",
Expand Down
4 changes: 2 additions & 2 deletions src/jwe/compact/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export interface CompactDecryptGetKey extends GetKeyFunction<JWEHeaderParameters
*/
async function compactDecrypt(
jwe: string | Uint8Array,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: DecryptOptions,
): Promise<CompactDecryptResult>
/**
Expand All @@ -67,7 +67,7 @@ async function compactDecrypt(
): Promise<CompactDecryptResult & ResolvedKey>
async function compactDecrypt(
jwe: string | Uint8Array,
key: KeyLike | CompactDecryptGetKey,
key: KeyLike | Uint8Array | CompactDecryptGetKey,
options?: DecryptOptions,
) {
if (jwe instanceof Uint8Array) {
Expand Down
2 changes: 1 addition & 1 deletion src/jwe/compact/encrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class CompactEncrypt {
* @param key Public Key or Secret to encrypt the JWE with.
* @param options JWE Encryption options.
*/
async encrypt(key: KeyLike, options?: EncryptOptions): Promise<string> {
async encrypt(key: KeyLike | Uint8Array, options?: EncryptOptions): Promise<string> {
const jwe = await this._flattened.encrypt(key, options)

return [jwe.protected, jwe.encrypted_key, jwe.iv, jwe.ciphertext, jwe.tag].join('.')
Expand Down
6 changes: 3 additions & 3 deletions src/jwe/flattened/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export interface FlattenedDecryptGetKey
*/
function flattenedDecrypt(
jwe: FlattenedJWE,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: DecryptOptions,
): Promise<FlattenedDecryptResult>
/**
Expand All @@ -95,7 +95,7 @@ function flattenedDecrypt(
): Promise<FlattenedDecryptResult & ResolvedKey>
async function flattenedDecrypt(
jwe: FlattenedJWE,
key: KeyLike | FlattenedDecryptGetKey,
key: KeyLike | Uint8Array | FlattenedDecryptGetKey,
options?: DecryptOptions,
) {
if (!isObject(jwe)) {
Expand Down Expand Up @@ -205,7 +205,7 @@ async function flattenedDecrypt(
resolvedKey = true
}

let cek: KeyLike
let cek: KeyLike | Uint8Array
try {
cek = await decryptKeyManagement(alg, key, encryptedKey, joseHeader)
} catch (err) {
Expand Down
7 changes: 3 additions & 4 deletions src/jwe/flattened/encrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import type {
JWEKeyManagementHeaderParameters,
EncryptOptions,
} from '../../types.d'
import type { JWEKeyManagementHeaderResults } from '../../types.i.d'
import ivFactory from '../../lib/iv.js'
import encryptKeyManagement from '../../lib/encrypt_key_management.js'
import { JOSENotSupported, JWEInvalid } from '../../util/errors.js'
Expand Down Expand Up @@ -182,7 +181,7 @@ class FlattenedEncrypt {
* @param key Public Key or Secret to encrypt the JWE with.
* @param options JWE Encryption options.
*/
async encrypt(key: KeyLike, options?: EncryptOptions) {
async encrypt(key: KeyLike | Uint8Array, options?: EncryptOptions) {
if (!this._protectedHeader && !this._unprotectedHeader && !this._sharedUnprotectedHeader) {
throw new JWEInvalid(
'either setProtectedHeader, setUnprotectedHeader, or sharedUnprotectedHeader must be called before #encrypt()',
Expand Down Expand Up @@ -241,9 +240,9 @@ class FlattenedEncrypt {
}
}

let cek: KeyLike
let cek: KeyLike | Uint8Array
{
let parameters: JWEKeyManagementHeaderResults | undefined
let parameters: { [propName: string]: unknown } | undefined
;({ cek, encryptedKey, parameters } = await encryptKeyManagement(
alg,
enc,
Expand Down
4 changes: 2 additions & 2 deletions src/jwe/general/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export interface GeneralDecryptGetKey extends GetKeyFunction<JWEHeaderParameters
*/
function generalDecrypt(
jwe: GeneralJWE,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: DecryptOptions,
): Promise<GeneralDecryptResult>
/**
Expand All @@ -84,7 +84,7 @@ function generalDecrypt(
): Promise<GeneralDecryptResult & ResolvedKey>
async function generalDecrypt(
jwe: GeneralJWE,
key: KeyLike | GeneralDecryptGetKey,
key: KeyLike | Uint8Array | GeneralDecryptGetKey,
options?: DecryptOptions,
) {
if (!isObject(jwe)) {
Expand Down
2 changes: 1 addition & 1 deletion src/jwk/embedded.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async function EmbeddedJWK(protectedHeader: JWSHeaderParameters, token: Flattene

const key = await importJWK({ ...joseHeader.jwk, ext: true }, joseHeader.alg!, true)

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

Expand Down
2 changes: 1 addition & 1 deletion src/jwk/from_key_like.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { JWK, KeyLike } from '../types.d'
/**
* @deprecated use `jose/key/export`
*/
async function fromKeyLike(key: KeyLike): Promise<JWK> {
async function fromKeyLike(key: KeyLike | Uint8Array): Promise<JWK> {
return exportJWK(key)
}

Expand Down
6 changes: 5 additions & 1 deletion src/jwk/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import type { JWK, KeyLike } from '../types.d'
/**
* @deprecated use `jose/key/import`
*/
async function parseJwk(jwk: JWK, alg?: string, octAsKeyObject?: boolean): Promise<KeyLike> {
async function parseJwk(
jwk: JWK,
alg?: string,
octAsKeyObject?: boolean,
): Promise<KeyLike | Uint8Array> {
return importJWK(jwk, alg, octAsKeyObject)
}

Expand Down
12 changes: 6 additions & 6 deletions src/jwks/remote.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fetchJwks from '../runtime/fetch_jwks.js'

import type {
KeyObject,
KeyLike,
JWSHeaderParameters,
JWK,
FlattenedJWSInput,
Expand Down Expand Up @@ -31,7 +31,7 @@ function getKtyFromAlg(alg: unknown) {
}

interface Cache {
[alg: string]: KeyObject | CryptoKey
[alg: string]: KeyLike
}

/**
Expand Down Expand Up @@ -62,8 +62,8 @@ export interface RemoteJWKSetOptions {
agent?: any
}

function isJWKLike(key: unknown): key is JWK {
return isObject(key)
function isJWKLike(key: unknown) {
return isObject<JWK>(key)
}

class RemoteJWKSet {
Expand Down Expand Up @@ -103,7 +103,7 @@ class RemoteJWKSet {
return Date.now() < this._cooldownStarted + this._cooldownDuration
}

async getKey(protectedHeader: JWSHeaderParameters): Promise<KeyObject | CryptoKey> {
async getKey(protectedHeader: JWSHeaderParameters): Promise<KeyLike> {
if (!this._jwks) {
await this.reload()
}
Expand Down Expand Up @@ -175,7 +175,7 @@ class RemoteJWKSet {
if (cached[protectedHeader.alg!] === undefined) {
const keyObject = await importJWK({ ...jwk, ext: true }, protectedHeader.alg!)

if (!('type' in keyObject) || keyObject.type !== 'public') {
if (keyObject instanceof Uint8Array || keyObject.type !== 'public') {
throw new JWKSInvalid('JSON Web Key Set members must be public keys')
}

Expand Down
2 changes: 1 addition & 1 deletion src/jws/compact/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class CompactSign {
* @param key Private Key or Secret to sign the JWS with.
* @param options JWS Sign options.
*/
async sign(key: KeyLike, options?: SignOptions): Promise<string> {
async sign(key: KeyLike | Uint8Array, options?: SignOptions): Promise<string> {
const jws = await this._flattened.sign(key, options)

if (jws.payload === undefined) {
Expand Down
4 changes: 2 additions & 2 deletions src/jws/compact/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export interface CompactVerifyGetKey
*/
function compactVerify(
jws: string | Uint8Array,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: VerifyOptions,
): Promise<CompactVerifyResult>
/**
Expand All @@ -71,7 +71,7 @@ function compactVerify(
): Promise<CompactVerifyResult & ResolvedKey>
async function compactVerify(
jws: string | Uint8Array,
key: KeyLike | CompactVerifyGetKey,
key: KeyLike | Uint8Array | CompactVerifyGetKey,
options?: VerifyOptions,
) {
if (jws instanceof Uint8Array) {
Expand Down
2 changes: 1 addition & 1 deletion src/jws/flattened/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class FlattenedSign {
* @param key Private Key or Secret to sign the JWS with.
* @param options JWS Sign options.
*/
async sign(key: KeyLike, options?: SignOptions): Promise<FlattenedJWS> {
async sign(key: KeyLike | Uint8Array, options?: SignOptions): Promise<FlattenedJWS> {
if (!this._protectedHeader && !this._unprotectedHeader) {
throw new JWSInvalid(
'either setProtectedHeader or setUnprotectedHeader must be called before #sign()',
Expand Down
4 changes: 2 additions & 2 deletions src/jws/flattened/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export interface FlattenedVerifyGetKey
*/
function flattenedVerify(
jws: FlattenedJWSInput,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: VerifyOptions,
): Promise<FlattenedVerifyResult>
/**
Expand All @@ -86,7 +86,7 @@ function flattenedVerify(
): Promise<FlattenedVerifyResult & ResolvedKey>
async function flattenedVerify(
jws: FlattenedJWSInput,
key: KeyLike | FlattenedVerifyGetKey,
key: KeyLike | Uint8Array | FlattenedVerifyGetKey,
options?: VerifyOptions,
) {
if (!isObject(jws)) {
Expand Down
4 changes: 2 additions & 2 deletions src/jws/general/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface SignatureReference {
protectedHeader?: JWSHeaderParameters
unprotectedHeader?: JWSHeaderParameters
options?: SignOptions
key: KeyLike
key: KeyLike | Uint8Array
}

const signatureRef: WeakMap<IndividualSignature, SignatureReference> = new WeakMap()
Expand Down Expand Up @@ -109,7 +109,7 @@ class GeneralSign {
this._payload = payload
}

addSignature(key: KeyLike, options?: SignOptions): Signature {
addSignature(key: KeyLike | Uint8Array, options?: SignOptions): Signature {
const signature = new IndividualSignature()
signatureRef.set(signature, { key, options })
this._signatures.push(signature)
Expand Down
4 changes: 2 additions & 2 deletions src/jws/general/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export interface GeneralVerifyGetKey
*/
function generalVerify(
jws: GeneralJWSInput,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: VerifyOptions,
): Promise<GeneralVerifyResult>
/**
Expand All @@ -80,7 +80,7 @@ function generalVerify(
): Promise<GeneralVerifyResult & ResolvedKey>
async function generalVerify(
jws: GeneralJWSInput,
key: KeyLike | GeneralVerifyGetKey,
key: KeyLike | Uint8Array | GeneralVerifyGetKey,
options?: VerifyOptions,
) {
if (!isObject(jws)) {
Expand Down
4 changes: 2 additions & 2 deletions src/jwt/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export interface JWTDecryptGetKey extends GetKeyFunction<JWEHeaderParameters, Fl
*/
async function jwtDecrypt(
jwt: string | Uint8Array,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: JWTDecryptOptions,
): Promise<JWTDecryptResult>
/**
Expand All @@ -76,7 +76,7 @@ async function jwtDecrypt(
): Promise<JWTDecryptResult & ResolvedKey>
async function jwtDecrypt(
jwt: string | Uint8Array,
key: KeyLike | JWTDecryptGetKey,
key: KeyLike | Uint8Array | JWTDecryptGetKey,
options?: JWTDecryptOptions,
) {
const decrypted = await decrypt(jwt, <Parameters<typeof decrypt>[1]>key, options)
Expand Down
4 changes: 2 additions & 2 deletions src/jwt/encrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {
KeyLike,
} from '../types.d'
import { encoder } from '../lib/buffer_utils.js'
import ProduceJWT from '../lib/jwt_producer.js'
import { ProduceJWT } from './produce.js'

/**
* The EncryptJWT class is a utility for creating Compact JWE formatted JWT strings.
Expand Down Expand Up @@ -151,7 +151,7 @@ class EncryptJWT extends ProduceJWT {
* @param key Public Key or Secret to encrypt the JWT with.
* @param options JWE Encryption options.
*/
async encrypt(key: KeyLike, options?: EncryptOptions): Promise<string> {
async encrypt(key: KeyLike | Uint8Array, options?: EncryptOptions): Promise<string> {
const enc = new CompactEncrypt(encoder.encode(JSON.stringify(this._payload)))
if (this._replicateIssuerAsHeader) {
this._protectedHeader = { ...this._protectedHeader, iss: this._payload.iss }
Expand Down
8 changes: 4 additions & 4 deletions src/lib/jwt_producer.ts → src/jwt/produce.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { JWTPayload } from '../types.d'
import epoch from './epoch.js'
import isObject from './is_object.js'
import secs from './secs.js'
import epoch from '../lib/epoch.js'
import isObject from '../lib/is_object.js'
import secs from '../lib/secs.js'

/**
* Generic class for JWT producing.
*/
export default class ProduceJWT {
export class ProduceJWT {
protected _payload!: JWTPayload

/**
Expand Down
4 changes: 2 additions & 2 deletions src/jwt/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import CompactSign from '../jws/compact/sign.js'
import { JWTInvalid } from '../util/errors.js'
import type { JWSHeaderParameters, JWTPayload, KeyLike, SignOptions } from '../types.d'
import { encoder } from '../lib/buffer_utils.js'
import ProduceJWT from '../lib/jwt_producer.js'
import { ProduceJWT } from './produce.js'

/**
* The SignJWT class is a utility for creating Compact JWS formatted JWT strings.
Expand Down Expand Up @@ -54,7 +54,7 @@ class SignJWT extends ProduceJWT {
* @param key Private Key or Secret to sign the JWT with.
* @param options JWT Sign options.
*/
async sign(key: KeyLike, options?: SignOptions): Promise<string> {
async sign(key: KeyLike | Uint8Array, options?: SignOptions): Promise<string> {
const sig = new CompactSign(encoder.encode(JSON.stringify(this._payload)))
sig.setProtectedHeader(this._protectedHeader)
if (
Expand Down
2 changes: 1 addition & 1 deletion src/jwt/unsecured.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { JWSHeaderParameters, JWTClaimVerificationOptions, JWTPayload } fro
import { decoder } from '../lib/buffer_utils.js'
import { JWTInvalid } from '../util/errors.js'
import jwtPayload from '../lib/jwt_claims_set.js'
import ProduceJWT from '../lib/jwt_producer.js'
import { ProduceJWT } from './produce.js'

interface UnsecuredResult {
payload: JWTPayload
Expand Down
4 changes: 2 additions & 2 deletions src/jwt/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export interface JWTVerifyGetKey extends GetKeyFunction<JWSHeaderParameters, Fla
*/
async function jwtVerify(
jwt: string | Uint8Array,
key: KeyLike,
key: KeyLike | Uint8Array,
options?: JWTVerifyOptions,
): Promise<JWTVerifyResult>
/**
Expand All @@ -79,7 +79,7 @@ async function jwtVerify(
): Promise<JWTVerifyResult & ResolvedKey>
async function jwtVerify(
jwt: string | Uint8Array,
key: KeyLike | JWTVerifyGetKey,
key: KeyLike | Uint8Array | JWTVerifyGetKey,
options?: JWTVerifyOptions,
) {
const verified = await verify(jwt, <Parameters<typeof verify>[1]>key, options)
Expand Down

0 comments on commit a13eb04

Please sign in to comment.