From 52e4e0884ec59e3422dc18ed9357fc7dae81758c Mon Sep 17 00:00:00 2001 From: Chris Barth Date: Sat, 8 Jul 2023 08:00:27 -0400 Subject: [PATCH] lint --- .eslintrc.json | 5 ++-- package-lock.json | 2 +- src/c14n-canonicalization.ts | 34 +++++++++++++++--------- src/enveloped-signature.ts | 44 +++++++++++++++++++------------ src/exclusive-canonicalization.ts | 4 +-- src/hash-algorithms.ts | 4 --- src/signature-algorithms.ts | 5 ---- src/signed-xml.ts | 19 +++++++------ src/types.ts | 37 +++++++++++++++++--------- src/utils.ts | 6 ++--- tsconfig.eslint.json | 2 +- tsconfig.json | 3 ++- 12 files changed, 93 insertions(+), 72 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index eec9a997..c409610e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -19,7 +19,7 @@ ], "rules": { "no-console": "error", - "no-unused-vars": "error", + "no-unused-vars": "warn", "no-prototype-builtins": "error", "one-var": ["error", "never"], "no-duplicate-imports": "error", @@ -30,6 +30,7 @@ "prefer-const": "error", "deprecation/deprecation": "warn", "@typescript-eslint/no-non-null-assertion": "error", - "@typescript-eslint/no-unused-vars": "error" + "@typescript-eslint/no-unused-vars": "warn", + "@typescript-eslint/no-this-alias": "warn" } } diff --git a/package-lock.json b/package-lock.json index 6f0f07c9..0ad23a8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8573,7 +8573,7 @@ "dev": true }, "xpath": { - "version": "git+https://github.com/goto100/xpath.git#ab20282cd085f4d236c00f21975ebe5e139f7bdb", + "version": "git+https://github.com/goto100/xpath.git#a78cedf42292c3c85e15be4c91ae697cc3b2122b", "from": "git+https://github.com/goto100/xpath.git#pull/116/head" }, "y18n": { diff --git a/src/c14n-canonicalization.ts b/src/c14n-canonicalization.ts index 7feb1c25..c4cea68c 100644 --- a/src/c14n-canonicalization.ts +++ b/src/c14n-canonicalization.ts @@ -1,10 +1,13 @@ -import { CanonicalizationOrTransformationAlgorithm, ProcessOptions } from "./types"; +import { + CanonicalizationOrTransformationAlgorithm, + NamespacePrefix, + ProcessOptions, + RenderedNamespace, +} from "./types"; import * as utils from "./utils"; export class C14nCanonicalization implements CanonicalizationOrTransformationAlgorithm { - includeComments: boolean = false; - - constructor() {} + includeComments = false; attrCompare(a, b) { if (!a.namespaceURI && b.namespaceURI) { @@ -67,16 +70,21 @@ export class C14nCanonicalization implements CanonicalizationOrTransformationAlg /** * Create the string of all namespace declarations that should appear on this element * - * @param {Node} node. The node we now render - * @param {Array} prefixesInScope. The prefixes defined on this node + * @param node. The node we now render + * @param prefixesInScope. The prefixes defined on this node * parents which are a part of the output set - * @param {String} defaultNs. The current default namespace - * @param {String} defaultNsForPrefix. - * @param {String} ancestorNamespaces - Import ancestor namespaces if it is specified - * @return {String} + * @param defaultNs. The current default namespace + * @param defaultNsForPrefix. + * @param ancestorNamespaces - Import ancestor namespaces if it is specified * @api private */ - renderNs(node, prefixesInScope, defaultNs, defaultNsForPrefix, ancestorNamespaces) { + renderNs( + node: Element, + prefixesInScope: string[], + defaultNs: string, + defaultNsForPrefix: string, + ancestorNamespaces: NamespacePrefix[] + ): RenderedNamespace { let i; let attr; const res: string[] = []; @@ -95,7 +103,7 @@ export class C14nCanonicalization implements CanonicalizationOrTransformationAlg } } else if (defaultNs !== currNs) { //new default ns - newDefaultNs = node.namespaceURI; + newDefaultNs = node.namespaceURI || ""; res.push(' xmlns="', newDefaultNs, '"'); } @@ -149,7 +157,7 @@ export class C14nCanonicalization implements CanonicalizationOrTransformationAlg //render namespaces res.push(...nsListToRender.map((attr) => ` xmlns:${attr.prefix}="${attr.namespaceURI}"`)); - return { rendered: res.join(""), newDefaultNs: newDefaultNs }; + return { rendered: res.join(""), newDefaultNs }; } processInner(node, prefixesInScope, defaultNs, defaultNsForPrefix, ancestorNamespaces) { diff --git a/src/enveloped-signature.ts b/src/enveloped-signature.ts index ae4c4666..ab898bd4 100644 --- a/src/enveloped-signature.ts +++ b/src/enveloped-signature.ts @@ -1,19 +1,20 @@ -const xpath = require("xpath"); +import * as xpath from "xpath"; + import { CanonicalizationOrTransformationAlgorithm, CanonicalizationOrTransformationAlgorithmProcessOptions, CanonicalizationOrTransformAlgorithmType, } from "./types"; -import * as utils from "./utils"; + export class EnvelopedSignature implements CanonicalizationOrTransformationAlgorithm { - includeComments: boolean = false; + includeComments = false; process(node: Node, options: CanonicalizationOrTransformationAlgorithmProcessOptions) { if (null == options.signatureNode) { - const signature = xpath.select( + const signature = xpath.select1( "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", node - )[0]; - if (signature) { + ); + if (xpath.isNodeLike(signature) && signature.parentNode) { signature.parentNode.removeChild(signature); } return node; @@ -22,18 +23,27 @@ export class EnvelopedSignature implements CanonicalizationOrTransformationAlgor const expectedSignatureValue = xpath.select1( ".//*[local-name(.)='SignatureValue']/text()", signatureNode - ).data; - const signatures = xpath.select( - ".//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", - node ); - for (const nodeSignature of signatures) { - const signatureValue = xpath.select1( - ".//*[local-name(.)='SignatureValue']/text()", - nodeSignature - ).data; - if (expectedSignatureValue === signatureValue) { - nodeSignature.parentNode.removeChild(nodeSignature); + if (xpath.isTextNode(expectedSignatureValue)) { + const expectedSignatureValueData = expectedSignatureValue.data; + + const signatures = xpath.select( + ".//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", + node + ); + for (const nodeSignature of Array.isArray(signatures) ? signatures : []) { + const signatureValue = xpath.select1( + ".//*[local-name(.)='SignatureValue']/text()", + nodeSignature + ); + if (xpath.isTextNode(signatureValue)) { + const signatureValueData = signatureValue.data; + if (expectedSignatureValueData === signatureValueData) { + if (nodeSignature.parentNode) { + nodeSignature.parentNode.removeChild(nodeSignature); + } + } + } } } return node; diff --git a/src/exclusive-canonicalization.ts b/src/exclusive-canonicalization.ts index f8c8dbc0..567d9204 100644 --- a/src/exclusive-canonicalization.ts +++ b/src/exclusive-canonicalization.ts @@ -13,9 +13,7 @@ function isPrefixInScope(prefixesInScope, prefix, namespaceURI) { } export class ExclusiveCanonicalization implements CanonicalizationOrTransformationAlgorithm { - includeComments: boolean = false; - - constructor() {} + includeComments = false; attrCompare(a, b) { if (!a.namespaceURI && b.namespaceURI) { diff --git a/src/hash-algorithms.ts b/src/hash-algorithms.ts index 5d59dbde..56f6c896 100644 --- a/src/hash-algorithms.ts +++ b/src/hash-algorithms.ts @@ -2,7 +2,6 @@ import * as crypto from "crypto"; import { HashAlgorithm } from "./types"; export class Sha1 implements HashAlgorithm { - constructor() {} getHash = function (xml) { const shasum = crypto.createHash("sha1"); shasum.update(xml, "utf8"); @@ -16,8 +15,6 @@ export class Sha1 implements HashAlgorithm { } export class Sha256 implements HashAlgorithm { - constructor() {} - getHash = function (xml) { const shasum = crypto.createHash("sha256"); shasum.update(xml, "utf8"); @@ -31,7 +28,6 @@ export class Sha256 implements HashAlgorithm { } export class Sha512 implements HashAlgorithm { - constructor() {} getHash = function (xml) { const shasum = crypto.createHash("sha512"); shasum.update(xml, "utf8"); diff --git a/src/signature-algorithms.ts b/src/signature-algorithms.ts index 3b823341..71a23ed8 100644 --- a/src/signature-algorithms.ts +++ b/src/signature-algorithms.ts @@ -2,8 +2,6 @@ import * as crypto from "crypto"; import { SignatureAlgorithm, createOptionalCallbackFunction } from "./types"; export class RsaSha1 implements SignatureAlgorithm { - constructor() {} - getSignature = createOptionalCallbackFunction( (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { const signer = crypto.createSign("RSA-SHA1"); @@ -30,7 +28,6 @@ export class RsaSha1 implements SignatureAlgorithm { } export class RsaSha256 implements SignatureAlgorithm { - constructor() {} getSignature = createOptionalCallbackFunction( (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { const signer = crypto.createSign("RSA-SHA256"); @@ -57,7 +54,6 @@ export class RsaSha256 implements SignatureAlgorithm { } export class RsaSha512 implements SignatureAlgorithm { - constructor() {} getSignature = createOptionalCallbackFunction( (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { const signer = crypto.createSign("RSA-SHA512"); @@ -84,7 +80,6 @@ export class RsaSha512 implements SignatureAlgorithm { } export class HmacSha1 implements SignatureAlgorithm { - constructor() {} getSignature = createOptionalCallbackFunction( (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { const signer = crypto.createHmac("SHA1", privateKey); diff --git a/src/signed-xml.ts b/src/signed-xml.ts index 6fa2567e..a5879e83 100644 --- a/src/signed-xml.ts +++ b/src/signed-xml.ts @@ -13,15 +13,14 @@ import { ErrorFirstCallback, } from "./types"; -const xpath = require("xpath"); -const xmldom = require("@xmldom/xmldom"); -const Dom = require("@xmldom/xmldom").DOMParser; +import * as xpath from "xpath"; +import { DOMParser as Dom } from "@xmldom/xmldom"; import * as utils from "./utils"; -const c14n = require("./c14n-canonicalization"); -const execC14n = require("./exclusive-canonicalization"); -const envelopedSignatures = require("./enveloped-signature"); -const hashAlgorithms = require("./hash-algorithms"); -const signatureAlgorithms = require("./signature-algorithms"); +import * as c14n from "./c14n-canonicalization"; +import * as execC14n from "./exclusive-canonicalization"; +import * as envelopedSignatures from "./enveloped-signature"; +import * as hashAlgorithms from "./hash-algorithms"; +import * as signatureAlgorithms from "./signature-algorithms"; import * as crypto from "crypto"; export class SignedXml { @@ -44,7 +43,7 @@ export class SignedXml { /** * It specifies a list of namespace prefixes that should be considered "inclusive" during the canonicalization process. */ - inclusiveNamespacesPrefixList: string = ""; + inclusiveNamespacesPrefixList = ""; namespaceResolver: XPathNSResolver = { lookupNamespaceURI: function (prefix) { throw new Error("Not implemented"); @@ -786,7 +785,7 @@ export class SignedXml { } this.signatureNode = signatureDoc; - let signedInfoNodes = utils.findChilds(this.signatureNode, "SignedInfo"); + const signedInfoNodes = utils.findChilds(this.signatureNode, "SignedInfo"); if (signedInfoNodes.length === 0) { const err3 = new Error("could not find SignedInfo element in the message"); if (!callback) { diff --git a/src/types.ts b/src/types.ts index 6f615fb1..71aa3670 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-unused-vars */ // Type definitions for @node-saml/xml-crypto // Project: https://github.com/node-saml/xml-crypto#readme // Original definitions by: Eric Heikes @@ -7,6 +8,8 @@ import * as crypto from "crypto"; +export type ErrorFirstCallback = (err: Error | null, result?: T) => void; + export type CanonicalizationAlgorithmType = | "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" | "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" @@ -31,6 +34,15 @@ export type SignatureAlgorithmType = | "http://www.w3.org/2000/09/xmldsig#hmac-sha1" | string; +/** + * @param cert the certificate as a string or array of strings (see https://www.w3.org/TR/2008/REC-xmldsig-core-20080610/#sec-X509Data) + * @param prefix an optional namespace alias to be used for the generated XML + */ +export type GetKeyInfoContentArgs = { + publicCert?: crypto.KeyLike; + prefix?: string | null; +}; + /** * Options for the SignedXml constructor. */ @@ -52,15 +64,21 @@ export type NamespacePrefix = { prefix: string; namespaceURI: string; }; + export type ProcessOptions = { defaultNs?: string; defaultNsForPrefix?: NamespacePrefix; ancestorNamespaces?: NamespacePrefix[]; }; +export type RenderedNamespace = { + rendered: string; + newDefaultNs: string; +}; + export type CanonicalizationOrTransformationAlgorithmProcessOptions = { defaultNs?: string; - defaultForPrefix?: {}; + defaultForPrefix?: object; ancestorNamespaces?: []; signatureNode: Node; }; @@ -186,17 +204,6 @@ export interface TransformAlgorithm { * - {@link SignedXml#validationErrors} */ -/** - * @param cert the certificate as a string or array of strings (see https://www.w3.org/TR/2008/REC-xmldsig-core-20080610/#sec-X509Data) - * @param prefix an optional namespace alias to be used for the generated XML - */ -export type GetKeyInfoContentArgs = { - publicCert?: crypto.KeyLike; - prefix?: string | null; -}; - -export type ErrorFirstCallback = (err: Error | null, result?: T) => void; - /** * This function will add a callback version of a sync function. * @@ -223,3 +230,9 @@ export function createOptionalCallbackFunction( } }) as any; } + +declare global { + interface ArrayConstructor { + isArray(arg: unknown): arg is Array | ReadonlyArray; + } +} diff --git a/src/utils.ts b/src/utils.ts index 34db1554..f59d2995 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -265,15 +265,15 @@ export function validateDigestValue(digest, expectedDigest) { let buffer; let expectedBuffer; - const majorVersion = /^v(\d+)/.exec(process.version)![1]; + const majorVersion = (/^v(\d+)/.exec(process.version) || [0, 0])[1]; if (+majorVersion >= 6) { buffer = Buffer.from(digest, "base64"); expectedBuffer = Buffer.from(expectedDigest, "base64"); } else { // Compatibility with Node < 5.10.0 - buffer = new Buffer(digest, "base64"); - expectedBuffer = new Buffer(expectedDigest, "base64"); + buffer = Buffer.from(digest, "base64"); + expectedBuffer = Buffer.from(expectedDigest, "base64"); } if (typeof buffer.equals === "function") { diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index fba20009..28bc604f 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -1,5 +1,5 @@ { "extends": "./tsconfig.json", "exclude": [], - "include": ["test"] + "include": ["test", "src"] } diff --git a/tsconfig.json b/tsconfig.json index 7d122662..03136e85 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -65,5 +65,6 @@ "skipLibCheck": true /* Skip type checking of declaration files. */, "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ }, - "exclude": ["node_modules", "docs", "lib", "test", "coverage", "example"] + "exclude": ["node_modules", "docs", "lib", "test", "coverage", "example"], + "include": ["src"] }