@verdaccio/signature 7.0.0-next.3 → 8.0.0-next-8.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @verdaccio/signature
2
2
 
3
+ ## 8.0.0-next-8.0
4
+
5
+ ### Major Changes
6
+
7
+ - chore: move v7 next to v8 next
8
+
9
+ ## 7.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - 47f61c6: feat!: bump to v7
14
+ - e7ebccb: update major dependencies, remove old nodejs support
15
+
16
+ ### Minor Changes
17
+
18
+ - daceb6d: restore legacy support
19
+ - b6d5652: support for createCipher backward compatible
20
+ - f047cc8: refactor: auth with legacy sign support
21
+ - bd8703e: feat: add migrateToSecureLegacySignature and remove enhancedLegacySignature property
22
+
23
+ ### Patch Changes
24
+
25
+ - 312bc10: chore: export signature options type
26
+
27
+ ## 7.0.0-next-7.5
28
+
29
+ ### Minor Changes
30
+
31
+ - bd8703e: feat: add migrateToSecureLegacySignature and remove enhancedLegacySignature property
32
+
33
+ ## 7.0.0-next-7.4
34
+
35
+ ### Minor Changes
36
+
37
+ - b6d5652: support for createCipher backward compatible
38
+
3
39
  ## 7.0.0-next.3
4
40
 
5
41
  ### Minor Changes
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Verdaccio contributors
3
+ Copyright (c) 2024 Verdaccio contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/build/index.js CHANGED
@@ -67,5 +67,5 @@ var _types = _interopRequireWildcard(require("./types"));
67
67
  exports.types = _types;
68
68
  var _token = require("./token");
69
69
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
70
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
70
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
71
71
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_legacySignature","require","_signature","_jwtToken","_utils","_interopRequireWildcard","exports","utils","_types","types","_token","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set"],"sources":["../src/index.ts"],"sourcesContent":["export {\n aesDecryptDeprecated,\n aesEncryptDeprecated,\n generateRandomSecretKeyDeprecated,\n} from './legacy-signature';\nexport { aesDecrypt, aesEncrypt } from './signature';\nexport { signPayload, verifyPayload, SignOptionsSignature } from './jwt-token';\nexport * as utils from './utils';\nexport * as types from './types';\nexport { parseBasicPayload } from './token';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,gBAAA,GAAAC,OAAA;AAKA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,SAAA,GAAAF,OAAA;AAA+E,IAAAG,MAAA,GAAAC,uBAAA,CAAAJ,OAAA;AAAAK,OAAA,CAAAC,KAAA,GAAAH,MAAA;AAAA,IAAAI,MAAA,GAAAH,uBAAA,CAAAJ,OAAA;AAAAK,OAAA,CAAAG,KAAA,GAAAD,MAAA;AAG/E,IAAAE,MAAA,GAAAT,OAAA;AAA4C,SAAAU,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAP,wBAAAO,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAjB,CAAA,EAAAc,CAAA,SAAAI,CAAA,GAAAR,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAI,CAAA,KAAAA,CAAA,CAAAX,GAAA,IAAAW,CAAA,CAAAC,GAAA,IAAAR,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAI,CAAA,IAAAV,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAgB,GAAA,CAAAnB,CAAA,EAAAQ,CAAA,GAAAA,CAAA"}
1
+ {"version":3,"file":"index.js","names":["_legacySignature","require","_signature","_jwtToken","_utils","_interopRequireWildcard","exports","utils","_types","types","_token","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set"],"sources":["../src/index.ts"],"sourcesContent":["export {\n aesDecryptDeprecated,\n aesEncryptDeprecated,\n generateRandomSecretKeyDeprecated,\n} from './legacy-signature';\n\nexport { aesDecrypt, aesEncrypt } from './signature';\nexport { signPayload, verifyPayload, SignOptionsSignature } from './jwt-token';\nexport * as utils from './utils';\nexport * as types from './types';\nexport { parseBasicPayload } from './token';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,gBAAA,GAAAC,OAAA;AAMA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,SAAA,GAAAF,OAAA;AAA+E,IAAAG,MAAA,GAAAC,uBAAA,CAAAJ,OAAA;AAAAK,OAAA,CAAAC,KAAA,GAAAH,MAAA;AAAA,IAAAI,MAAA,GAAAH,uBAAA,CAAAJ,OAAA;AAAAK,OAAA,CAAAG,KAAA,GAAAD,MAAA;AAG/E,IAAAE,MAAA,GAAAT,OAAA;AAA4C,SAAAU,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAP,wBAAAO,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAc,CAAA,SAAAG,CAAA,GAAAP,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAG,CAAA,KAAAA,CAAA,CAAAV,GAAA,IAAAU,CAAA,CAAAC,GAAA,IAAAP,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAG,CAAA,IAAAT,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAe,GAAA,CAAAlB,CAAA,EAAAQ,CAAA,GAAAA,CAAA","ignoreList":[]}
@@ -7,7 +7,7 @@ exports.signPayload = signPayload;
7
7
  exports.verifyPayload = verifyPayload;
8
8
  var _debug = _interopRequireDefault(require("debug"));
9
9
  var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
11
  const debug = (0, _debug.default)('verdaccio:auth:token:jwt');
12
12
  /**
13
13
  * Sign the payload and return JWT
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-token.js","names":["_debug","_interopRequireDefault","require","_jsonwebtoken","obj","__esModule","default","debug","buildDebug","signPayload","payload","secretOrPrivateKey","options","Promise","resolve","reject","jwt","sign","notBefore","error","token","message","verifyPayload","verify"],"sources":["../src/jwt-token.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport jwt, { SignOptions } from 'jsonwebtoken';\n\nimport { RemoteUser } from '@verdaccio/types';\n\nexport type SignOptionsSignature = Pick<SignOptions, 'algorithm' | 'expiresIn' | 'notBefore'>;\n\nconst debug = buildDebug('verdaccio:auth:token:jwt');\n/**\n * Sign the payload and return JWT\n * https://github.com/auth0/node-jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback\n * @param payload\n * @param secretOrPrivateKey\n * @param options\n */\nexport async function signPayload(\n payload: RemoteUser,\n secretOrPrivateKey: string,\n options: SignOptionsSignature = {}\n): Promise<string> {\n return new Promise(function (resolve, reject) {\n debug('sign jwt token');\n jwt.sign(\n payload,\n secretOrPrivateKey, // FIXME: upgrade to the latest library and types\n {\n // 1 === 1ms (one millisecond)\n notBefore: '1', // Make sure the time will not rollback :)\n ...options,\n },\n (error, token) => {\n if (error) {\n debug('error on sign jwt token %s', error.message);\n return reject(error);\n }\n debug('signed jwt token successfully');\n return resolve(token as string);\n }\n );\n });\n}\n\nexport function verifyPayload(token: string, secretOrPrivateKey: string): RemoteUser {\n debug('verifying jwt token');\n return jwt.verify(token, secretOrPrivateKey) as RemoteUser;\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,aAAA,GAAAF,sBAAA,CAAAC,OAAA;AAAgD,SAAAD,uBAAAG,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAMhD,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,0BAA0B,CAAC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeC,WAAWA,CAC/BC,OAAmB,EACnBC,kBAA0B,EAC1BC,OAA6B,GAAG,CAAC,CAAC,EACjB;EACjB,OAAO,IAAIC,OAAO,CAAC,UAAUC,OAAO,EAAEC,MAAM,EAAE;IAC5CR,KAAK,CAAC,gBAAgB,CAAC;IACvBS,qBAAG,CAACC,IAAI,CACNP,OAAO,EACPC,kBAAkB;IAAE;IACpB;MACE;MACAO,SAAS,EAAE,GAAG;MAAE;MAChB,GAAGN;IACL,CAAC,EACD,CAACO,KAAK,EAAEC,KAAK,KAAK;MAChB,IAAID,KAAK,EAAE;QACTZ,KAAK,CAAC,4BAA4B,EAAEY,KAAK,CAACE,OAAO,CAAC;QAClD,OAAON,MAAM,CAACI,KAAK,CAAC;MACtB;MACAZ,KAAK,CAAC,+BAA+B,CAAC;MACtC,OAAOO,OAAO,CAACM,KAAe,CAAC;IACjC,CACF,CAAC;EACH,CAAC,CAAC;AACJ;AAEO,SAASE,aAAaA,CAACF,KAAa,EAAET,kBAA0B,EAAc;EACnFJ,KAAK,CAAC,qBAAqB,CAAC;EAC5B,OAAOS,qBAAG,CAACO,MAAM,CAACH,KAAK,EAAET,kBAAkB,CAAC;AAC9C"}
1
+ {"version":3,"file":"jwt-token.js","names":["_debug","_interopRequireDefault","require","_jsonwebtoken","e","__esModule","default","debug","buildDebug","signPayload","payload","secretOrPrivateKey","options","Promise","resolve","reject","jwt","sign","notBefore","error","token","message","verifyPayload","verify"],"sources":["../src/jwt-token.ts"],"sourcesContent":["import buildDebug from 'debug';\nimport jwt, { SignOptions } from 'jsonwebtoken';\n\nimport { RemoteUser } from '@verdaccio/types';\n\nexport type SignOptionsSignature = Pick<SignOptions, 'algorithm' | 'expiresIn' | 'notBefore'>;\n\nconst debug = buildDebug('verdaccio:auth:token:jwt');\n/**\n * Sign the payload and return JWT\n * https://github.com/auth0/node-jsonwebtoken#jwtsignpayload-secretorprivatekey-options-callback\n * @param payload\n * @param secretOrPrivateKey\n * @param options\n */\nexport async function signPayload(\n payload: RemoteUser,\n secretOrPrivateKey: string,\n options: SignOptionsSignature = {}\n): Promise<string> {\n return new Promise(function (resolve, reject) {\n debug('sign jwt token');\n jwt.sign(\n payload,\n secretOrPrivateKey, // FIXME: upgrade to the latest library and types\n {\n // 1 === 1ms (one millisecond)\n notBefore: '1', // Make sure the time will not rollback :)\n ...options,\n },\n (error, token) => {\n if (error) {\n debug('error on sign jwt token %s', error.message);\n return reject(error);\n }\n debug('signed jwt token successfully');\n return resolve(token as string);\n }\n );\n });\n}\n\nexport function verifyPayload(token: string, secretOrPrivateKey: string): RemoteUser {\n debug('verifying jwt token');\n return jwt.verify(token, secretOrPrivateKey) as RemoteUser;\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,aAAA,GAAAF,sBAAA,CAAAC,OAAA;AAAgD,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAMhD,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,0BAA0B,CAAC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeC,WAAWA,CAC/BC,OAAmB,EACnBC,kBAA0B,EAC1BC,OAA6B,GAAG,CAAC,CAAC,EACjB;EACjB,OAAO,IAAIC,OAAO,CAAC,UAAUC,OAAO,EAAEC,MAAM,EAAE;IAC5CR,KAAK,CAAC,gBAAgB,CAAC;IACvBS,qBAAG,CAACC,IAAI,CACNP,OAAO,EACPC,kBAAkB;IAAE;IACpB;MACE;MACAO,SAAS,EAAE,GAAG;MAAE;MAChB,GAAGN;IACL,CAAC,EACD,CAACO,KAAK,EAAEC,KAAK,KAAK;MAChB,IAAID,KAAK,EAAE;QACTZ,KAAK,CAAC,4BAA4B,EAAEY,KAAK,CAACE,OAAO,CAAC;QAClD,OAAON,MAAM,CAACI,KAAK,CAAC;MACtB;MACAZ,KAAK,CAAC,+BAA+B,CAAC;MACtC,OAAOO,OAAO,CAACM,KAAe,CAAC;IACjC,CACF,CAAC;EACH,CAAC,CAAC;AACJ;AAEO,SAASE,aAAaA,CAACF,KAAa,EAAET,kBAA0B,EAAc;EACnFJ,KAAK,CAAC,qBAAqB,CAAC;EAC5B,OAAOS,qBAAG,CAACO,MAAM,CAACH,KAAK,EAAET,kBAAkB,CAAC;AAC9C","ignoreList":[]}
@@ -9,9 +9,12 @@ exports.aesEncryptDeprecated = aesEncryptDeprecated;
9
9
  exports.defaultTarballHashAlgorithm = exports.defaultAlgorithm = void 0;
10
10
  exports.generateRandomSecretKeyDeprecated = generateRandomSecretKeyDeprecated;
11
11
  var _crypto = require("crypto");
12
+ var _debug = _interopRequireDefault(require("debug"));
12
13
  var _utils = require("../utils");
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
15
  const defaultAlgorithm = exports.defaultAlgorithm = 'aes192';
14
16
  const defaultTarballHashAlgorithm = exports.defaultTarballHashAlgorithm = 'sha1';
17
+ const debug = (0, _debug.default)('verdaccio:auth:token:legacy:deprecated');
15
18
 
16
19
  /**
17
20
  *
@@ -20,12 +23,15 @@ const defaultTarballHashAlgorithm = exports.defaultTarballHashAlgorithm = 'sha1'
20
23
  * @returns
21
24
  */
22
25
  function aesEncryptDeprecated(buf, secret) {
26
+ debug('aesEncryptDeprecated init');
27
+ debug('algorithm %o', defaultAlgorithm);
23
28
  // deprecated (it will be removed in Verdaccio 6), it is a breaking change
24
29
  // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options
25
30
  // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/
26
31
  const c = (0, _crypto.createCipher)(defaultAlgorithm, secret);
27
32
  const b1 = c.update(buf);
28
33
  const b2 = c.final();
34
+ debug('deprecated legacy token generated successfully');
29
35
  return Buffer.concat([b1, b2]);
30
36
  }
31
37
 
@@ -37,11 +43,13 @@ function aesEncryptDeprecated(buf, secret) {
37
43
  */
38
44
  function aesDecryptDeprecated(buf, secret) {
39
45
  try {
46
+ debug('aesDecryptDeprecated init');
40
47
  // https://nodejs.org/api/crypto.html#crypto_crypto_createdecipher_algorithm_password_options
41
48
  // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/
42
49
  const c = (0, _crypto.createDecipher)(defaultAlgorithm, secret);
43
50
  const b1 = c.update(buf);
44
51
  const b2 = c.final();
52
+ debug('deprecated legacy token payload decrypted successfully');
45
53
  return Buffer.concat([b1, b2]);
46
54
  } catch (_) {
47
55
  return Buffer.alloc(0);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_crypto","require","_utils","defaultAlgorithm","exports","defaultTarballHashAlgorithm","aesEncryptDeprecated","buf","secret","c","createCipher","b1","update","b2","final","Buffer","concat","aesDecryptDeprecated","createDecipher","_","alloc","TOKEN_VALID_LENGTH_DEPRECATED","generateRandomSecretKeyDeprecated","generateRandomHexString"],"sources":["../../src/legacy-signature/index.ts"],"sourcesContent":["import { createCipher, createDecipher } from 'crypto';\n\nimport { generateRandomHexString } from '../utils';\n\nexport const defaultAlgorithm = 'aes192';\nexport const defaultTarballHashAlgorithm = 'sha1';\n\n/**\n *\n * @param buf\n * @param secret\n * @returns\n */\nexport function aesEncryptDeprecated(buf: Buffer, secret: string): Buffer {\n // deprecated (it will be removed in Verdaccio 6), it is a breaking change\n // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options\n // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/\n const c = createCipher(defaultAlgorithm, secret);\n const b1 = c.update(buf);\n const b2 = c.final();\n return Buffer.concat([b1, b2]);\n}\n\n/**\n *\n * @param buf\n * @param secret\n * @returns\n */\nexport function aesDecryptDeprecated(buf: Buffer, secret: string): Buffer {\n try {\n // https://nodejs.org/api/crypto.html#crypto_crypto_createdecipher_algorithm_password_options\n // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/\n const c = createDecipher(defaultAlgorithm, secret);\n const b1 = c.update(buf);\n const b2 = c.final();\n return Buffer.concat([b1, b2]);\n } catch (_) {\n return Buffer.alloc(0);\n }\n}\n\nexport const TOKEN_VALID_LENGTH_DEPRECATED = 64;\n\n/**\n * Generate a secret key of 64 characters.\n */\nexport function generateRandomSecretKeyDeprecated(): string {\n return generateRandomHexString(6);\n}\n"],"mappings":";;;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAEA,IAAAC,MAAA,GAAAD,OAAA;AAEO,MAAME,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG,QAAQ;AACjC,MAAME,2BAA2B,GAAAD,OAAA,CAAAC,2BAAA,GAAG,MAAM;;AAEjD;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,oBAAoBA,CAACC,GAAW,EAAEC,MAAc,EAAU;EACxE;EACA;EACA;EACA,MAAMC,CAAC,GAAG,IAAAC,oBAAY,EAACP,gBAAgB,EAAEK,MAAM,CAAC;EAChD,MAAMG,EAAE,GAAGF,CAAC,CAACG,MAAM,CAACL,GAAG,CAAC;EACxB,MAAMM,EAAE,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC;EACpB,OAAOC,MAAM,CAACC,MAAM,CAAC,CAACL,EAAE,EAAEE,EAAE,CAAC,CAAC;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,oBAAoBA,CAACV,GAAW,EAAEC,MAAc,EAAU;EACxE,IAAI;IACF;IACA;IACA,MAAMC,CAAC,GAAG,IAAAS,sBAAc,EAACf,gBAAgB,EAAEK,MAAM,CAAC;IAClD,MAAMG,EAAE,GAAGF,CAAC,CAACG,MAAM,CAACL,GAAG,CAAC;IACxB,MAAMM,EAAE,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC;IACpB,OAAOC,MAAM,CAACC,MAAM,CAAC,CAACL,EAAE,EAAEE,EAAE,CAAC,CAAC;EAChC,CAAC,CAAC,OAAOM,CAAC,EAAE;IACV,OAAOJ,MAAM,CAACK,KAAK,CAAC,CAAC,CAAC;EACxB;AACF;AAEO,MAAMC,6BAA6B,GAAAjB,OAAA,CAAAiB,6BAAA,GAAG,EAAE;;AAE/C;AACA;AACA;AACO,SAASC,iCAAiCA,CAAA,EAAW;EAC1D,OAAO,IAAAC,8BAAuB,EAAC,CAAC,CAAC;AACnC"}
1
+ {"version":3,"file":"index.js","names":["_crypto","require","_debug","_interopRequireDefault","_utils","e","__esModule","default","defaultAlgorithm","exports","defaultTarballHashAlgorithm","debug","buildDebug","aesEncryptDeprecated","buf","secret","c","createCipher","b1","update","b2","final","Buffer","concat","aesDecryptDeprecated","createDecipher","_","alloc","TOKEN_VALID_LENGTH_DEPRECATED","generateRandomSecretKeyDeprecated","generateRandomHexString"],"sources":["../../src/legacy-signature/index.ts"],"sourcesContent":["import { createCipher, createDecipher } from 'crypto';\nimport buildDebug from 'debug';\n\nimport { generateRandomHexString } from '../utils';\n\nexport const defaultAlgorithm = 'aes192';\nexport const defaultTarballHashAlgorithm = 'sha1';\n\nconst debug = buildDebug('verdaccio:auth:token:legacy:deprecated');\n\n/**\n *\n * @param buf\n * @param secret\n * @returns\n */\nexport function aesEncryptDeprecated(buf: Buffer, secret: string): Buffer {\n debug('aesEncryptDeprecated init');\n debug('algorithm %o', defaultAlgorithm);\n // deprecated (it will be removed in Verdaccio 6), it is a breaking change\n // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options\n // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/\n const c = createCipher(defaultAlgorithm, secret);\n const b1 = c.update(buf);\n const b2 = c.final();\n debug('deprecated legacy token generated successfully');\n return Buffer.concat([b1, b2]);\n}\n\n/**\n *\n * @param buf\n * @param secret\n * @returns\n */\nexport function aesDecryptDeprecated(buf: Buffer, secret: string): Buffer {\n try {\n debug('aesDecryptDeprecated init');\n // https://nodejs.org/api/crypto.html#crypto_crypto_createdecipher_algorithm_password_options\n // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/\n const c = createDecipher(defaultAlgorithm, secret);\n const b1 = c.update(buf);\n const b2 = c.final();\n debug('deprecated legacy token payload decrypted successfully');\n return Buffer.concat([b1, b2]);\n } catch (_) {\n return Buffer.alloc(0);\n }\n}\n\nexport const TOKEN_VALID_LENGTH_DEPRECATED = 64;\n\n/**\n * Generate a secret key of 64 characters.\n */\nexport function generateRandomSecretKeyDeprecated(): string {\n return generateRandomHexString(6);\n}\n"],"mappings":";;;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAC,sBAAA,CAAAF,OAAA;AAEA,IAAAG,MAAA,GAAAH,OAAA;AAAmD,SAAAE,uBAAAE,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE5C,MAAMG,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG,QAAQ;AACjC,MAAME,2BAA2B,GAAAD,OAAA,CAAAC,2BAAA,GAAG,MAAM;AAEjD,MAAMC,KAAK,GAAG,IAAAC,cAAU,EAAC,wCAAwC,CAAC;;AAElE;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,oBAAoBA,CAACC,GAAW,EAAEC,MAAc,EAAU;EACxEJ,KAAK,CAAC,2BAA2B,CAAC;EAClCA,KAAK,CAAC,cAAc,EAAEH,gBAAgB,CAAC;EACvC;EACA;EACA;EACA,MAAMQ,CAAC,GAAG,IAAAC,oBAAY,EAACT,gBAAgB,EAAEO,MAAM,CAAC;EAChD,MAAMG,EAAE,GAAGF,CAAC,CAACG,MAAM,CAACL,GAAG,CAAC;EACxB,MAAMM,EAAE,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC;EACpBV,KAAK,CAAC,gDAAgD,CAAC;EACvD,OAAOW,MAAM,CAACC,MAAM,CAAC,CAACL,EAAE,EAAEE,EAAE,CAAC,CAAC;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,oBAAoBA,CAACV,GAAW,EAAEC,MAAc,EAAU;EACxE,IAAI;IACFJ,KAAK,CAAC,2BAA2B,CAAC;IAClC;IACA;IACA,MAAMK,CAAC,GAAG,IAAAS,sBAAc,EAACjB,gBAAgB,EAAEO,MAAM,CAAC;IAClD,MAAMG,EAAE,GAAGF,CAAC,CAACG,MAAM,CAACL,GAAG,CAAC;IACxB,MAAMM,EAAE,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC;IACpBV,KAAK,CAAC,wDAAwD,CAAC;IAC/D,OAAOW,MAAM,CAACC,MAAM,CAAC,CAACL,EAAE,EAAEE,EAAE,CAAC,CAAC;EAChC,CAAC,CAAC,OAAOM,CAAC,EAAE;IACV,OAAOJ,MAAM,CAACK,KAAK,CAAC,CAAC,CAAC;EACxB;AACF;AAEO,MAAMC,6BAA6B,GAAAnB,OAAA,CAAAmB,6BAAA,GAAG,EAAE;;AAE/C;AACA;AACA;AACO,SAASC,iCAAiCA,CAAA,EAAW;EAC1D,OAAO,IAAAC,8BAAuB,EAAC,CAAC,CAAC;AACnC","ignoreList":[]}
@@ -9,7 +9,7 @@ exports.defaultAlgorithm = void 0;
9
9
  var _crypto = require("crypto");
10
10
  var _debug = _interopRequireDefault(require("debug"));
11
11
  var _config = require("@verdaccio/config");
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  const debug = (0, _debug.default)('verdaccio:auth:token:legacy');
14
14
  const defaultAlgorithm = exports.defaultAlgorithm = process.env.VERDACCIO_LEGACY_ALGORITHM || 'aes-256-ctr';
15
15
  const inputEncoding = 'utf8';
@@ -18,14 +18,17 @@ const outputEncoding = 'hex';
18
18
  // https://stackoverflow.com/questions/50963160/invalid-key-length-in-crypto-createcipheriv#50963356
19
19
  const VERDACCIO_LEGACY_ENCRYPTION_KEY = process.env.VERDACCIO_LEGACY_ENCRYPTION_KEY;
20
20
  function aesEncrypt(value, key) {
21
+ debug('aesEncrypt init');
21
22
  // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options
22
23
  // https://www.grainger.xyz/posts/changing-from-cipher-to-cipheriv
23
- debug('encrypt %o', value);
24
24
  debug('algorithm %o', defaultAlgorithm);
25
25
  // IV must be a buffer of length 16
26
26
  const iv = (0, _crypto.randomBytes)(16);
27
27
  const secretKey = VERDACCIO_LEGACY_ENCRYPTION_KEY || key;
28
28
  const isKeyValid = (secretKey === null || secretKey === void 0 ? void 0 : secretKey.length) === _config.TOKEN_VALID_LENGTH;
29
+ if (isKeyValid === false) {
30
+ throw new Error('Invalid secret key length');
31
+ }
29
32
  debug('length secret key %o', secretKey === null || secretKey === void 0 ? void 0 : secretKey.length);
30
33
  debug('is valid secret %o', isKeyValid);
31
34
  if (!value || !secretKey || !isKeyValid) {
@@ -36,11 +39,12 @@ function aesEncrypt(value, key) {
36
39
  // @ts-ignore
37
40
  encrypted += cipher.final(outputEncoding);
38
41
  const token = `${iv.toString('hex')}:${encrypted.toString()}`;
39
- debug('token generated successfully');
42
+ debug('legacy token generated successfully');
40
43
  return Buffer.from(token).toString('base64');
41
44
  }
42
45
  function aesDecrypt(value, key) {
43
46
  try {
47
+ debug('aesDecrypt init');
44
48
  const buff = Buffer.from(value, 'base64');
45
49
  const textParts = buff.toString().split(':');
46
50
 
@@ -55,7 +59,7 @@ function aesDecrypt(value, key) {
55
59
  // FIXME: fix type here should allow Buffer
56
60
  let decrypted = decipher.update(encryptedText, outputEncoding, inputEncoding);
57
61
  decrypted += decipher.final(inputEncoding);
58
- debug('token decrypted successfully');
62
+ debug('legacy token payload decrypted successfully');
59
63
  return decrypted.toString();
60
64
  } catch (_) {
61
65
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"signature.js","names":["_crypto","require","_debug","_interopRequireDefault","_config","obj","__esModule","default","debug","buildDebug","defaultAlgorithm","exports","process","env","VERDACCIO_LEGACY_ALGORITHM","inputEncoding","outputEncoding","VERDACCIO_LEGACY_ENCRYPTION_KEY","aesEncrypt","value","key","iv","randomBytes","secretKey","isKeyValid","length","TOKEN_VALID_LENGTH","cipher","createCipheriv","encrypted","update","final","token","toString","Buffer","from","aesDecrypt","buff","textParts","split","IV","shift","encryptedText","join","decipher","createDecipheriv","decrypted","_"],"sources":["../src/signature.ts"],"sourcesContent":["import {\n BinaryToTextEncoding,\n CharacterEncoding,\n createCipheriv,\n createDecipheriv,\n randomBytes,\n} from 'crypto';\nimport buildDebug from 'debug';\n\nimport { TOKEN_VALID_LENGTH } from '@verdaccio/config';\n\nconst debug = buildDebug('verdaccio:auth:token:legacy');\n\nexport const defaultAlgorithm = process.env.VERDACCIO_LEGACY_ALGORITHM || 'aes-256-ctr';\nconst inputEncoding: CharacterEncoding = 'utf8';\nconst outputEncoding: BinaryToTextEncoding = 'hex';\n// Must be 256 bits (32 characters)\n// https://stackoverflow.com/questions/50963160/invalid-key-length-in-crypto-createcipheriv#50963356\nconst VERDACCIO_LEGACY_ENCRYPTION_KEY = process.env.VERDACCIO_LEGACY_ENCRYPTION_KEY;\n\nexport function aesEncrypt(value: string, key: string): string | void {\n // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options\n // https://www.grainger.xyz/posts/changing-from-cipher-to-cipheriv\n debug('encrypt %o', value);\n debug('algorithm %o', defaultAlgorithm);\n // IV must be a buffer of length 16\n const iv = randomBytes(16);\n const secretKey = VERDACCIO_LEGACY_ENCRYPTION_KEY || key;\n const isKeyValid = secretKey?.length === TOKEN_VALID_LENGTH;\n debug('length secret key %o', secretKey?.length);\n debug('is valid secret %o', isKeyValid);\n if (!value || !secretKey || !isKeyValid) {\n return;\n }\n\n const cipher = createCipheriv(defaultAlgorithm, secretKey, iv);\n let encrypted = cipher.update(value, inputEncoding, outputEncoding);\n // @ts-ignore\n encrypted += cipher.final(outputEncoding);\n const token = `${iv.toString('hex')}:${encrypted.toString()}`;\n debug('token generated successfully');\n return Buffer.from(token).toString('base64');\n}\n\nexport function aesDecrypt(value: string, key: string): string | void {\n try {\n const buff = Buffer.from(value, 'base64');\n const textParts = buff.toString().split(':');\n\n // extract the IV from the first half of the value\n // @ts-ignore\n const IV = Buffer.from(textParts.shift(), outputEncoding);\n // extract the encrypted text without the IV\n const encryptedText = Buffer.from(textParts.join(':'), outputEncoding);\n const secretKey = VERDACCIO_LEGACY_ENCRYPTION_KEY || key;\n // decipher the string\n const decipher = createDecipheriv(defaultAlgorithm, secretKey, IV);\n // FIXME: fix type here should allow Buffer\n let decrypted = decipher.update(encryptedText as any, outputEncoding, inputEncoding);\n decrypted += decipher.final(inputEncoding);\n debug('token decrypted successfully');\n return decrypted.toString();\n } catch (_: any) {\n return;\n }\n}\n"],"mappings":";;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAOA,IAAAC,MAAA,GAAAC,sBAAA,CAAAF,OAAA;AAEA,IAAAG,OAAA,GAAAH,OAAA;AAAuD,SAAAE,uBAAAE,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAEvD,MAAMG,KAAK,GAAG,IAAAC,cAAU,EAAC,6BAA6B,CAAC;AAEhD,MAAMC,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAGE,OAAO,CAACC,GAAG,CAACC,0BAA0B,IAAI,aAAa;AACvF,MAAMC,aAAgC,GAAG,MAAM;AAC/C,MAAMC,cAAoC,GAAG,KAAK;AAClD;AACA;AACA,MAAMC,+BAA+B,GAAGL,OAAO,CAACC,GAAG,CAACI,+BAA+B;AAE5E,SAASC,UAAUA,CAACC,KAAa,EAAEC,GAAW,EAAiB;EACpE;EACA;EACAZ,KAAK,CAAC,YAAY,EAAEW,KAAK,CAAC;EAC1BX,KAAK,CAAC,cAAc,EAAEE,gBAAgB,CAAC;EACvC;EACA,MAAMW,EAAE,GAAG,IAAAC,mBAAW,EAAC,EAAE,CAAC;EAC1B,MAAMC,SAAS,GAAGN,+BAA+B,IAAIG,GAAG;EACxD,MAAMI,UAAU,GAAG,CAAAD,SAAS,aAATA,SAAS,uBAATA,SAAS,CAAEE,MAAM,MAAKC,0BAAkB;EAC3DlB,KAAK,CAAC,sBAAsB,EAAEe,SAAS,aAATA,SAAS,uBAATA,SAAS,CAAEE,MAAM,CAAC;EAChDjB,KAAK,CAAC,oBAAoB,EAAEgB,UAAU,CAAC;EACvC,IAAI,CAACL,KAAK,IAAI,CAACI,SAAS,IAAI,CAACC,UAAU,EAAE;IACvC;EACF;EAEA,MAAMG,MAAM,GAAG,IAAAC,sBAAc,EAAClB,gBAAgB,EAAEa,SAAS,EAAEF,EAAE,CAAC;EAC9D,IAAIQ,SAAS,GAAGF,MAAM,CAACG,MAAM,CAACX,KAAK,EAAEJ,aAAa,EAAEC,cAAc,CAAC;EACnE;EACAa,SAAS,IAAIF,MAAM,CAACI,KAAK,CAACf,cAAc,CAAC;EACzC,MAAMgB,KAAK,GAAI,GAAEX,EAAE,CAACY,QAAQ,CAAC,KAAK,CAAE,IAAGJ,SAAS,CAACI,QAAQ,CAAC,CAAE,EAAC;EAC7DzB,KAAK,CAAC,8BAA8B,CAAC;EACrC,OAAO0B,MAAM,CAACC,IAAI,CAACH,KAAK,CAAC,CAACC,QAAQ,CAAC,QAAQ,CAAC;AAC9C;AAEO,SAASG,UAAUA,CAACjB,KAAa,EAAEC,GAAW,EAAiB;EACpE,IAAI;IACF,MAAMiB,IAAI,GAAGH,MAAM,CAACC,IAAI,CAAChB,KAAK,EAAE,QAAQ,CAAC;IACzC,MAAMmB,SAAS,GAAGD,IAAI,CAACJ,QAAQ,CAAC,CAAC,CAACM,KAAK,CAAC,GAAG,CAAC;;IAE5C;IACA;IACA,MAAMC,EAAE,GAAGN,MAAM,CAACC,IAAI,CAACG,SAAS,CAACG,KAAK,CAAC,CAAC,EAAEzB,cAAc,CAAC;IACzD;IACA,MAAM0B,aAAa,GAAGR,MAAM,CAACC,IAAI,CAACG,SAAS,CAACK,IAAI,CAAC,GAAG,CAAC,EAAE3B,cAAc,CAAC;IACtE,MAAMO,SAAS,GAAGN,+BAA+B,IAAIG,GAAG;IACxD;IACA,MAAMwB,QAAQ,GAAG,IAAAC,wBAAgB,EAACnC,gBAAgB,EAAEa,SAAS,EAAEiB,EAAE,CAAC;IAClE;IACA,IAAIM,SAAS,GAAGF,QAAQ,CAACd,MAAM,CAACY,aAAa,EAAS1B,cAAc,EAAED,aAAa,CAAC;IACpF+B,SAAS,IAAIF,QAAQ,CAACb,KAAK,CAAChB,aAAa,CAAC;IAC1CP,KAAK,CAAC,8BAA8B,CAAC;IACrC,OAAOsC,SAAS,CAACb,QAAQ,CAAC,CAAC;EAC7B,CAAC,CAAC,OAAOc,CAAM,EAAE;IACf;EACF;AACF"}
1
+ {"version":3,"file":"signature.js","names":["_crypto","require","_debug","_interopRequireDefault","_config","e","__esModule","default","debug","buildDebug","defaultAlgorithm","exports","process","env","VERDACCIO_LEGACY_ALGORITHM","inputEncoding","outputEncoding","VERDACCIO_LEGACY_ENCRYPTION_KEY","aesEncrypt","value","key","iv","randomBytes","secretKey","isKeyValid","length","TOKEN_VALID_LENGTH","Error","cipher","createCipheriv","encrypted","update","final","token","toString","Buffer","from","aesDecrypt","buff","textParts","split","IV","shift","encryptedText","join","decipher","createDecipheriv","decrypted","_"],"sources":["../src/signature.ts"],"sourcesContent":["import {\n BinaryToTextEncoding,\n CharacterEncoding,\n createCipheriv,\n createDecipheriv,\n randomBytes,\n} from 'crypto';\nimport buildDebug from 'debug';\n\nimport { TOKEN_VALID_LENGTH } from '@verdaccio/config';\n\nconst debug = buildDebug('verdaccio:auth:token:legacy');\n\nexport const defaultAlgorithm = process.env.VERDACCIO_LEGACY_ALGORITHM || 'aes-256-ctr';\nconst inputEncoding: CharacterEncoding = 'utf8';\nconst outputEncoding: BinaryToTextEncoding = 'hex';\n// Must be 256 bits (32 characters)\n// https://stackoverflow.com/questions/50963160/invalid-key-length-in-crypto-createcipheriv#50963356\nconst VERDACCIO_LEGACY_ENCRYPTION_KEY = process.env.VERDACCIO_LEGACY_ENCRYPTION_KEY;\n\nexport function aesEncrypt(value: string, key: string): string | void {\n debug('aesEncrypt init');\n // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options\n // https://www.grainger.xyz/posts/changing-from-cipher-to-cipheriv\n debug('algorithm %o', defaultAlgorithm);\n // IV must be a buffer of length 16\n const iv = randomBytes(16);\n const secretKey = VERDACCIO_LEGACY_ENCRYPTION_KEY || key;\n\n const isKeyValid = secretKey?.length === TOKEN_VALID_LENGTH;\n if (isKeyValid === false) {\n throw new Error('Invalid secret key length');\n }\n debug('length secret key %o', secretKey?.length);\n debug('is valid secret %o', isKeyValid);\n if (!value || !secretKey || !isKeyValid) {\n return;\n }\n\n const cipher = createCipheriv(defaultAlgorithm, secretKey, iv);\n let encrypted = cipher.update(value, inputEncoding, outputEncoding);\n // @ts-ignore\n encrypted += cipher.final(outputEncoding);\n const token = `${iv.toString('hex')}:${encrypted.toString()}`;\n debug('legacy token generated successfully');\n return Buffer.from(token).toString('base64');\n}\n\nexport function aesDecrypt(value: string, key: string): string | void {\n try {\n debug('aesDecrypt init');\n const buff = Buffer.from(value, 'base64');\n const textParts = buff.toString().split(':');\n\n // extract the IV from the first half of the value\n // @ts-ignore\n const IV = Buffer.from(textParts.shift(), outputEncoding);\n // extract the encrypted text without the IV\n const encryptedText = Buffer.from(textParts.join(':'), outputEncoding);\n const secretKey = VERDACCIO_LEGACY_ENCRYPTION_KEY || key;\n // decipher the string\n const decipher = createDecipheriv(defaultAlgorithm, secretKey, IV);\n // FIXME: fix type here should allow Buffer\n let decrypted = decipher.update(encryptedText as any, outputEncoding, inputEncoding);\n decrypted += decipher.final(inputEncoding);\n debug('legacy token payload decrypted successfully');\n return decrypted.toString();\n } catch (_: any) {\n return;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"token.js","names":["parseBasicPayload","credentials","index","indexOf","user","slice","password"],"sources":["../src/token.ts"],"sourcesContent":["import { BasicPayload } from './types';\n\n/**\n *\n * @param credentials\n * @returns\n */\nexport function parseBasicPayload(credentials: string): BasicPayload {\n const index = credentials.indexOf(':');\n if (index < 0) {\n return;\n }\n\n const user: string = credentials.slice(0, index);\n const password: string = credentials.slice(index + 1);\n\n return { user, password };\n}\n"],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACA;AACO,SAASA,iBAAiBA,CAACC,WAAmB,EAAgB;EACnE,MAAMC,KAAK,GAAGD,WAAW,CAACE,OAAO,CAAC,GAAG,CAAC;EACtC,IAAID,KAAK,GAAG,CAAC,EAAE;IACb;EACF;EAEA,MAAME,IAAY,GAAGH,WAAW,CAACI,KAAK,CAAC,CAAC,EAAEH,KAAK,CAAC;EAChD,MAAMI,QAAgB,GAAGL,WAAW,CAACI,KAAK,CAACH,KAAK,GAAG,CAAC,CAAC;EAErD,OAAO;IAAEE,IAAI;IAAEE;EAAS,CAAC;AAC3B"}
1
+ {"version":3,"file":"token.js","names":["parseBasicPayload","credentials","index","indexOf","user","slice","password"],"sources":["../src/token.ts"],"sourcesContent":["import { BasicPayload } from './types';\n\n/**\n *\n * @param credentials\n * @returns\n */\nexport function parseBasicPayload(credentials: string): BasicPayload {\n const index = credentials.indexOf(':');\n if (index < 0) {\n return;\n }\n\n const user: string = credentials.slice(0, index);\n const password: string = credentials.slice(index + 1);\n\n return { user, password };\n}\n"],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACA;AACO,SAASA,iBAAiBA,CAACC,WAAmB,EAAgB;EACnE,MAAMC,KAAK,GAAGD,WAAW,CAACE,OAAO,CAAC,GAAG,CAAC;EACtC,IAAID,KAAK,GAAG,CAAC,EAAE;IACb;EACF;EAEA,MAAME,IAAY,GAAGH,WAAW,CAACI,KAAK,CAAC,CAAC,EAAEH,KAAK,CAAC;EAChD,MAAMI,QAAgB,GAAGL,WAAW,CAACI,KAAK,CAACH,KAAK,GAAG,CAAC,CAAC;EAErD,OAAO;IAAEE,IAAI;IAAEE;EAAS,CAAC;AAC3B","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["export interface AESPayload {\n user: string;\n password: string;\n}\n\nexport type BasicPayload = AESPayload | void;\n"],"mappings":""}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["export interface AESPayload {\n user: string;\n password: string;\n}\n\nexport type BasicPayload = AESPayload | void;\n"],"mappings":"","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["_crypto","require","defaultTarballHashAlgorithm","exports","createTarballHash","algorithm","createHash","stringToMD5","data","update","digest","generateRandomHexString","length","pseudoRandomBytes","toString","TOKEN_VALID_LENGTH","generateRandomSecretKey","randomBytes","substring"],"sources":["../src/utils.ts"],"sourcesContent":["import { Hash, createHash, pseudoRandomBytes, randomBytes } from 'crypto';\n\nexport const defaultTarballHashAlgorithm = 'sha1';\n\n/**\n *\n * @returns\n */\nexport function createTarballHash(algorithm = defaultTarballHashAlgorithm): Hash {\n return createHash(algorithm);\n}\n\n/**\n * Express doesn't do ETAGS with requests <= 1024b\n * we use md5 here, it works well on 1k+ bytes, but with fewer data\n * could improve performance using crc32 after benchmarks.\n * @param {Object} data\n * @return {String}\n */\nexport function stringToMD5(data: Buffer | string): string {\n return createHash('md5').update(data).digest('hex');\n}\n\n/**\n *\n * @param length\n * @returns\n */\nexport function generateRandomHexString(length = 8): string {\n return pseudoRandomBytes(length).toString('hex');\n}\n\nexport const TOKEN_VALID_LENGTH = 32;\n\n/**\n * Generate a secret of 32 characters.\n */\nexport function generateRandomSecretKey(): string {\n return randomBytes(TOKEN_VALID_LENGTH).toString('base64').substring(0, TOKEN_VALID_LENGTH);\n}\n"],"mappings":";;;;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAEO,MAAMC,2BAA2B,GAAAC,OAAA,CAAAD,2BAAA,GAAG,MAAM;;AAEjD;AACA;AACA;AACA;AACO,SAASE,iBAAiBA,CAACC,SAAS,GAAGH,2BAA2B,EAAQ;EAC/E,OAAO,IAAAI,kBAAU,EAACD,SAAS,CAAC;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,WAAWA,CAACC,IAAqB,EAAU;EACzD,OAAO,IAAAF,kBAAU,EAAC,KAAK,CAAC,CAACG,MAAM,CAACD,IAAI,CAAC,CAACE,MAAM,CAAC,KAAK,CAAC;AACrD;;AAEA;AACA;AACA;AACA;AACA;AACO,SAASC,uBAAuBA,CAACC,MAAM,GAAG,CAAC,EAAU;EAC1D,OAAO,IAAAC,yBAAiB,EAACD,MAAM,CAAC,CAACE,QAAQ,CAAC,KAAK,CAAC;AAClD;AAEO,MAAMC,kBAAkB,GAAAZ,OAAA,CAAAY,kBAAA,GAAG,EAAE;;AAEpC;AACA;AACA;AACO,SAASC,uBAAuBA,CAAA,EAAW;EAChD,OAAO,IAAAC,mBAAW,EAACF,kBAAkB,CAAC,CAACD,QAAQ,CAAC,QAAQ,CAAC,CAACI,SAAS,CAAC,CAAC,EAAEH,kBAAkB,CAAC;AAC5F"}
1
+ {"version":3,"file":"utils.js","names":["_crypto","require","defaultTarballHashAlgorithm","exports","createTarballHash","algorithm","createHash","stringToMD5","data","update","digest","generateRandomHexString","length","pseudoRandomBytes","toString","TOKEN_VALID_LENGTH","generateRandomSecretKey","randomBytes","substring"],"sources":["../src/utils.ts"],"sourcesContent":["import { Hash, createHash, pseudoRandomBytes, randomBytes } from 'crypto';\n\nexport const defaultTarballHashAlgorithm = 'sha1';\n\n/**\n *\n * @returns\n */\nexport function createTarballHash(algorithm = defaultTarballHashAlgorithm): Hash {\n return createHash(algorithm);\n}\n\n/**\n * Express doesn't do ETAGS with requests <= 1024b\n * we use md5 here, it works well on 1k+ bytes, but with fewer data\n * could improve performance using crc32 after benchmarks.\n * @param {Object} data\n * @return {String}\n */\nexport function stringToMD5(data: Buffer | string): string {\n return createHash('md5').update(data).digest('hex');\n}\n\n/**\n *\n * @param length\n * @returns\n */\nexport function generateRandomHexString(length = 8): string {\n return pseudoRandomBytes(length).toString('hex');\n}\n\nexport const TOKEN_VALID_LENGTH = 32;\n\n/**\n * Generate a secret of 32 characters.\n */\nexport function generateRandomSecretKey(): string {\n return randomBytes(TOKEN_VALID_LENGTH).toString('base64').substring(0, TOKEN_VALID_LENGTH);\n}\n"],"mappings":";;;;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AAEO,MAAMC,2BAA2B,GAAAC,OAAA,CAAAD,2BAAA,GAAG,MAAM;;AAEjD;AACA;AACA;AACA;AACO,SAASE,iBAAiBA,CAACC,SAAS,GAAGH,2BAA2B,EAAQ;EAC/E,OAAO,IAAAI,kBAAU,EAACD,SAAS,CAAC;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,WAAWA,CAACC,IAAqB,EAAU;EACzD,OAAO,IAAAF,kBAAU,EAAC,KAAK,CAAC,CAACG,MAAM,CAACD,IAAI,CAAC,CAACE,MAAM,CAAC,KAAK,CAAC;AACrD;;AAEA;AACA;AACA;AACA;AACA;AACO,SAASC,uBAAuBA,CAACC,MAAM,GAAG,CAAC,EAAU;EAC1D,OAAO,IAAAC,yBAAiB,EAACD,MAAM,CAAC,CAACE,QAAQ,CAAC,KAAK,CAAC;AAClD;AAEO,MAAMC,kBAAkB,GAAAZ,OAAA,CAAAY,kBAAA,GAAG,EAAE;;AAEpC;AACA;AACA;AACO,SAASC,uBAAuBA,CAAA,EAAW;EAChD,OAAO,IAAAC,mBAAW,EAACF,kBAAkB,CAAC,CAACD,QAAQ,CAAC,QAAQ,CAAC,CAACI,SAAS,CAAC,CAAC,EAAEH,kBAAkB,CAAC;AAC5F","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdaccio/signature",
3
- "version": "7.0.0-next.3",
3
+ "version": "8.0.0-next-8.0",
4
4
  "description": "verdaccio signature utils",
5
5
  "main": "./build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -26,15 +26,15 @@
26
26
  "verdaccio"
27
27
  ],
28
28
  "engines": {
29
- "node": ">=12"
29
+ "node": ">=14"
30
30
  },
31
31
  "dependencies": {
32
32
  "jsonwebtoken": "9.0.2",
33
- "debug": "4.3.4"
33
+ "debug": "4.3.7"
34
34
  },
35
35
  "devDependencies": {
36
- "@verdaccio/config": "7.0.0-next.5",
37
- "@verdaccio/types": "12.0.0-next.2"
36
+ "@verdaccio/config": "8.0.0-next-8.0",
37
+ "@verdaccio/types": "13.0.0-next-8.0"
38
38
  },
39
39
  "funding": {
40
40
  "type": "opencollective",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "scripts": {
44
44
  "clean": "rimraf ./build",
45
- "test": "jest",
45
+ "test": "vitest run",
46
46
  "type-check": "tsc --noEmit -p tsconfig.build.json",
47
47
  "build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
48
48
  "build:js": "babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps",
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ export {
3
3
  aesEncryptDeprecated,
4
4
  generateRandomSecretKeyDeprecated,
5
5
  } from './legacy-signature';
6
+
6
7
  export { aesDecrypt, aesEncrypt } from './signature';
7
8
  export { signPayload, verifyPayload, SignOptionsSignature } from './jwt-token';
8
9
  export * as utils from './utils';
@@ -1,10 +1,13 @@
1
1
  import { createCipher, createDecipher } from 'crypto';
2
+ import buildDebug from 'debug';
2
3
 
3
4
  import { generateRandomHexString } from '../utils';
4
5
 
5
6
  export const defaultAlgorithm = 'aes192';
6
7
  export const defaultTarballHashAlgorithm = 'sha1';
7
8
 
9
+ const debug = buildDebug('verdaccio:auth:token:legacy:deprecated');
10
+
8
11
  /**
9
12
  *
10
13
  * @param buf
@@ -12,12 +15,15 @@ export const defaultTarballHashAlgorithm = 'sha1';
12
15
  * @returns
13
16
  */
14
17
  export function aesEncryptDeprecated(buf: Buffer, secret: string): Buffer {
18
+ debug('aesEncryptDeprecated init');
19
+ debug('algorithm %o', defaultAlgorithm);
15
20
  // deprecated (it will be removed in Verdaccio 6), it is a breaking change
16
21
  // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options
17
22
  // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/
18
23
  const c = createCipher(defaultAlgorithm, secret);
19
24
  const b1 = c.update(buf);
20
25
  const b2 = c.final();
26
+ debug('deprecated legacy token generated successfully');
21
27
  return Buffer.concat([b1, b2]);
22
28
  }
23
29
 
@@ -29,11 +35,13 @@ export function aesEncryptDeprecated(buf: Buffer, secret: string): Buffer {
29
35
  */
30
36
  export function aesDecryptDeprecated(buf: Buffer, secret: string): Buffer {
31
37
  try {
38
+ debug('aesDecryptDeprecated init');
32
39
  // https://nodejs.org/api/crypto.html#crypto_crypto_createdecipher_algorithm_password_options
33
40
  // https://www.grainger.xyz/changing-from-cipher-to-cipheriv/
34
41
  const c = createDecipher(defaultAlgorithm, secret);
35
42
  const b1 = c.update(buf);
36
43
  const b2 = c.final();
44
+ debug('deprecated legacy token payload decrypted successfully');
37
45
  return Buffer.concat([b1, b2]);
38
46
  } catch (_) {
39
47
  return Buffer.alloc(0);
package/src/signature.ts CHANGED
@@ -19,14 +19,18 @@ const outputEncoding: BinaryToTextEncoding = 'hex';
19
19
  const VERDACCIO_LEGACY_ENCRYPTION_KEY = process.env.VERDACCIO_LEGACY_ENCRYPTION_KEY;
20
20
 
21
21
  export function aesEncrypt(value: string, key: string): string | void {
22
+ debug('aesEncrypt init');
22
23
  // https://nodejs.org/api/crypto.html#crypto_crypto_createcipher_algorithm_password_options
23
24
  // https://www.grainger.xyz/posts/changing-from-cipher-to-cipheriv
24
- debug('encrypt %o', value);
25
25
  debug('algorithm %o', defaultAlgorithm);
26
26
  // IV must be a buffer of length 16
27
27
  const iv = randomBytes(16);
28
28
  const secretKey = VERDACCIO_LEGACY_ENCRYPTION_KEY || key;
29
+
29
30
  const isKeyValid = secretKey?.length === TOKEN_VALID_LENGTH;
31
+ if (isKeyValid === false) {
32
+ throw new Error('Invalid secret key length');
33
+ }
30
34
  debug('length secret key %o', secretKey?.length);
31
35
  debug('is valid secret %o', isKeyValid);
32
36
  if (!value || !secretKey || !isKeyValid) {
@@ -38,12 +42,13 @@ export function aesEncrypt(value: string, key: string): string | void {
38
42
  // @ts-ignore
39
43
  encrypted += cipher.final(outputEncoding);
40
44
  const token = `${iv.toString('hex')}:${encrypted.toString()}`;
41
- debug('token generated successfully');
45
+ debug('legacy token generated successfully');
42
46
  return Buffer.from(token).toString('base64');
43
47
  }
44
48
 
45
49
  export function aesDecrypt(value: string, key: string): string | void {
46
50
  try {
51
+ debug('aesDecrypt init');
47
52
  const buff = Buffer.from(value, 'base64');
48
53
  const textParts = buff.toString().split(':');
49
54
 
@@ -58,7 +63,7 @@ export function aesDecrypt(value: string, key: string): string | void {
58
63
  // FIXME: fix type here should allow Buffer
59
64
  let decrypted = decipher.update(encryptedText as any, outputEncoding, inputEncoding);
60
65
  decrypted += decipher.final(inputEncoding);
61
- debug('token decrypted successfully');
66
+ debug('legacy token payload decrypted successfully');
62
67
  return decrypted.toString();
63
68
  } catch (_: any) {
64
69
  return;
package/test/jwt.spec.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { describe, expect, test } from 'vitest';
2
+
1
3
  import { createRemoteUser } from '@verdaccio/config';
2
4
 
3
5
  import { signPayload, verifyPayload } from '../src';
@@ -1,14 +1,26 @@
1
+ import { describe, expect, test } from 'vitest';
2
+
3
+ import { isNodeVersionGreaterThan21 } from '@verdaccio/config';
4
+
1
5
  import {
2
6
  aesDecryptDeprecated,
3
7
  aesEncryptDeprecated,
4
8
  generateRandomSecretKeyDeprecated,
5
9
  } from '../src';
6
10
 
7
- describe('test deprecated crypto utils', () => {
11
+ const itdescribe = (condition) => (condition ? describe : describe.skip);
12
+
13
+ itdescribe(isNodeVersionGreaterThan21() === false)('test deprecated crypto utils', () => {
14
+ test('generateRandomSecretKeyDeprecated', () => {
15
+ expect(generateRandomSecretKeyDeprecated()).toHaveLength(12);
16
+ });
17
+
8
18
  test('decrypt payload flow', () => {
9
- const secret = generateRandomSecretKeyDeprecated();
19
+ const secret = '4b4512c6ce20';
10
20
  const payload = 'juan:password';
11
21
  const token = aesEncryptDeprecated(Buffer.from(payload), secret);
22
+
23
+ expect(token.toString('base64')).toEqual('auizc1j3lSEd2wEB5CyGbQ==');
12
24
  const data = aesDecryptDeprecated(token, secret);
13
25
 
14
26
  expect(data.toString()).toEqual(payload.toString());
@@ -1,3 +1,5 @@
1
+ import { describe, expect, test } from 'vitest';
2
+
1
3
  import { aesDecrypt, aesEncrypt } from '../src';
2
4
 
3
5
  describe('test crypto utils', () => {
@@ -13,7 +15,6 @@ describe('test crypto utils', () => {
13
15
  test('crypt fails if secret is incorrect', () => {
14
16
  const secret = 'f5bb945cc57fea2f25961e1bd6fb3c89_TO_LONG';
15
17
  const payload = 'juan';
16
- const token = aesEncrypt(payload, secret) as string;
17
- expect(token).toBeUndefined();
18
+ expect(() => aesEncrypt(payload, secret)).toThrow('Invalid secret key length');
18
19
  });
19
20
  });
@@ -1,3 +1,5 @@
1
+ import { expect, test } from 'vitest';
2
+
1
3
  import {
2
4
  TOKEN_VALID_LENGTH,
3
5
  createTarballHash,
package/jest.config.js DELETED
@@ -1,3 +0,0 @@
1
- const config = require('../../jest/config');
2
-
3
- module.exports = Object.assign({}, config, {});