fritzbox-api
Version:
Straightforward, lightweight and extendable Node.js library to communicate with FRITZ!Box devices
81 lines (65 loc) • 2.71 kB
JavaScript
// Copyright (c) 2026, Thorsten A. Weintz. All rights reserved.
// Licensed under the MIT license. See LICENSE in the project root for license information.
import HashUtil from './hashUtil.mjs';
/**
* Helper class for handling HTTP Digest Authentication.
* Provides parsing and header generation utilities.
*/
class DigestAuthHelper {
/**
* Parses a Digest authentication header string into an object.
*
* @param {string} header Raw Digest header string.
* @returns {Object<string, string>} Key-value pairs extracted from the header.
*/
static parseDigest(header) {
const parts = {};
header.replace(/(\w+)=("([^"]*)"|[^,]*)/g, (_, k, v, v2) => {
parts[k] = v2 ?? v.replace(/"/g, '');
});
return parts;
}
/**
* Builds a Digest Authorization header for an HTTP request.
*
* @param {Object} param0 Authentication parameters.
* @param {string} param0.username Username for authentication.
* @param {string} param0.password Password for authentication.
* @param {string} param0.method HTTP method (e.g., GET, POST).
* @param {string} param0.uri Request URI.
* @param {Object} digestData Parsed digest challenge data from server.
* @param {string} digestData.realm Authentication realm.
* @param {string} digestData.nonce Server-provided nonce.
* @param {string} digestData.qop Quality of protection (e.g., auth).
* @returns {string} Digest Authorization header value.
*/
static buildDigestAuthHeader({ username, password, method, uri }, digestData) {
const md5 = HashUtil.md5;
const cnonce = HashUtil.randomHex(8);
const nc = '00000001';
const qopRaw = digestData.qop?.replace(/"/g, '');
const qop = qopRaw === 'auth' ? 'auth' : null;
const HA1 = md5(`${username}:${digestData.realm}:${password}`);
const HA2 = md5(`${method}:${uri}`);
const response = qop
? md5(`${HA1}:${digestData.nonce}:${nc}:${cnonce}:${qop}:${HA2}`)
: md5(`${HA1}:${digestData.nonce}:${HA2}`);
let header =
`Digest username="${username}", ` +
`realm="${digestData.realm}", ` +
`nonce="${digestData.nonce}", ` +
`uri="${uri}"`;
if (qop) {
header +=
`, qop=${qop}` +
`, nc=${nc}` +
`, cnonce="${cnonce}"`;
}
header += `, response="${response}"`;
return header;
}
}
/**
* Exports @see DigestAuthHelper as default class.
*/
export default DigestAuthHelper;