musicbrainz-api 0.10.3 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,101 +0,0 @@
1
- import { v4 as uuidv4 } from 'uuid';
2
- import * as crypto from 'crypto';
3
-
4
- interface IChallenge {
5
- algorithm?: string;
6
- realm?: string;
7
- nonce?: string;
8
- opaque?: string;
9
- qop?: string;
10
- }
11
-
12
- export interface ICredentials {
13
- username: string;
14
- password: string;
15
- }
16
-
17
- function md5(str) {
18
- return crypto.createHash('md5').update(str).digest('hex'); // lgtm [js/insufficient-password-hash]
19
- }
20
-
21
- export class DigestAuth {
22
-
23
- /**
24
- * RFC 2617: handle both MD5 and MD5-sess algorithms.
25
- *
26
- * If the algorithm directive's value is "MD5" or unspecified, then HA1 is
27
- * HA1=MD5(username:realm:password)
28
- * If the algorithm directive's value is "MD5-sess", then HA1 is
29
- * HA1=MD5(MD5(username:realm:password):nonce:cnonce)
30
- */
31
- public static ha1Compute(algorithm, user, realm, pass, nonce, cnonce) {
32
- const ha1 = md5(user + ':' + realm + ':' + pass); // lgtm [js/insufficient-password-hash]
33
- return algorithm && algorithm.toLowerCase() === 'md5-sess' ? md5(ha1 + ':' + nonce + ':' + cnonce) : ha1;
34
- }
35
-
36
- public hasAuth: boolean;
37
- public sentAuth: boolean;
38
- public bearerToken: string;
39
-
40
- public constructor(private credentials: ICredentials) {
41
- this.hasAuth = false;
42
- this.sentAuth = false;
43
- this.bearerToken = null;
44
- }
45
-
46
- public digest(method: string, path: string, authHeader: string): string {
47
- // TODO: More complete implementation of RFC 2617.
48
- // - support qop="auth-int" only
49
- // - handle Authentication-Info (not necessarily?)
50
- // - check challenge.stale (not necessarily?)
51
- // - increase nc (not necessarily?)
52
- // For reference:
53
- // http://tools.ietf.org/html/rfc2617#section-3
54
- // https://github.com/bagder/curl/blob/master/lib/http_digest.c
55
-
56
- const challenge: IChallenge = {};
57
- const re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi;
58
- while (true) {
59
- const match = re.exec(authHeader);
60
- if (!match) {
61
- break;
62
- }
63
- challenge[match[1]] = match[2] || match[3];
64
- }
65
-
66
- const qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth';
67
- const nc = qop && '00000001';
68
- const cnonce = qop && uuidv4().replace(/-/g, '');
69
- const ha1 = DigestAuth.ha1Compute(challenge.algorithm, this.credentials.username, challenge.realm, this.credentials.password, challenge.nonce, cnonce);
70
- const ha2 = md5(method + ':' + path); // lgtm [js/insufficient-password-hash]
71
- const digestResponse = qop
72
- ? md5(ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2) // lgtm [js/insufficient-password-hash]
73
- : md5(ha1 + ':' + challenge.nonce + ':' + ha2); // lgtm [js/insufficient-password-hash]
74
- const authValues = {
75
- username: this.credentials.username,
76
- realm: challenge.realm,
77
- nonce: challenge.nonce,
78
- uri: path,
79
- qop,
80
- response: digestResponse,
81
- nc,
82
- cnonce,
83
- algorithm: challenge.algorithm,
84
- opaque: challenge.opaque
85
- };
86
-
87
- const parts: string[] = [];
88
- for (const k in authValues) {
89
- if (authValues[k]) {
90
- if (k === 'qop' || k === 'nc' || k === 'algorithm') {
91
- parts.push(k + '=' + authValues[k]);
92
- } else {
93
- parts.push(k + '="' + authValues[k] + '"');
94
- }
95
- }
96
- }
97
- authHeader = 'Digest ' + parts.join(', ');
98
- this.sentAuth = true;
99
- return authHeader;
100
- }
101
- }