@hemia/jwt-manager 0.0.1 → 0.0.2

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.
@@ -23,7 +23,7 @@ var safeBuffer = {exports: {}};
23
23
 
24
24
  /*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
25
25
 
26
- (function (module, exports) {
26
+ (function (module, exports$1) {
27
27
  /* eslint-disable node/no-deprecated-api */
28
28
  var buffer = require$$0;
29
29
  var Buffer = buffer.Buffer;
@@ -38,8 +38,8 @@ var safeBuffer = {exports: {}};
38
38
  module.exports = buffer;
39
39
  } else {
40
40
  // Copy properties from require('buffer')
41
- copyProps(buffer, exports);
42
- exports.Buffer = SafeBuffer;
41
+ copyProps(buffer, exports$1);
42
+ exports$1.Buffer = SafeBuffer;
43
43
  }
44
44
 
45
45
  function SafeBuffer (arg, encodingOrOffset, length) {
@@ -660,7 +660,7 @@ var jwa$2 = function jwa(algorithm) {
660
660
  es: createECDSAVerifer,
661
661
  none: createNoneVerifier,
662
662
  };
663
- var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/i);
663
+ var match = algorithm.match(/^(RS|PS|ES|HS)(256|384|512)$|^(none)$/);
664
664
  if (!match)
665
665
  throw typeError(MSG_INVALID_ALGORITHM, algorithm);
666
666
  var algo = (match[1] || match[3]).toLowerCase();
@@ -721,7 +721,12 @@ function jwsSign(opts) {
721
721
  }
722
722
 
723
723
  function SignStream$1(opts) {
724
- var secret = opts.secret||opts.privateKey||opts.key;
724
+ var secret = opts.secret;
725
+ secret = secret == null ? opts.privateKey : secret;
726
+ secret = secret == null ? opts.key : secret;
727
+ if (/^hs/i.test(opts.header.alg) === true && secret == null) {
728
+ throw new TypeError('secret must be a string or buffer or a KeyObject')
729
+ }
725
730
  var secretStream = new DataStream$1(secret);
726
731
  this.readable = true;
727
732
  this.header = opts.header;
@@ -846,7 +851,12 @@ function jwsDecode(jwsSig, opts) {
846
851
 
847
852
  function VerifyStream$1(opts) {
848
853
  opts = opts || {};
849
- var secretOrKey = opts.secret||opts.publicKey||opts.key;
854
+ var secretOrKey = opts.secret;
855
+ secretOrKey = secretOrKey == null ? opts.publicKey : secretOrKey;
856
+ secretOrKey = secretOrKey == null ? opts.key : secretOrKey;
857
+ if (/^hs/i.test(opts.algorithm) === true && secretOrKey == null) {
858
+ throw new TypeError('secret must be a string or buffer or a KeyObject')
859
+ }
850
860
  var secretStream = new DataStream(secretOrKey);
851
861
  this.readable = true;
852
862
  this.algorithm = opts.algorithm;
@@ -1214,7 +1224,7 @@ const debug$1 = (
1214
1224
 
1215
1225
  var debug_1 = debug$1;
1216
1226
 
1217
- (function (module, exports) {
1227
+ (function (module, exports$1) {
1218
1228
 
1219
1229
  const {
1220
1230
  MAX_SAFE_COMPONENT_LENGTH,
@@ -1222,14 +1232,14 @@ var debug_1 = debug$1;
1222
1232
  MAX_LENGTH,
1223
1233
  } = constants$1;
1224
1234
  const debug = debug_1;
1225
- exports = module.exports = {};
1235
+ exports$1 = module.exports = {};
1226
1236
 
1227
1237
  // The actual regexps go on exports.re
1228
- const re = exports.re = [];
1229
- const safeRe = exports.safeRe = [];
1230
- const src = exports.src = [];
1231
- const safeSrc = exports.safeSrc = [];
1232
- const t = exports.t = {};
1238
+ const re = exports$1.re = [];
1239
+ const safeRe = exports$1.safeRe = [];
1240
+ const src = exports$1.src = [];
1241
+ const safeSrc = exports$1.safeSrc = [];
1242
+ const t = exports$1.t = {};
1233
1243
  let R = 0;
1234
1244
 
1235
1245
  const LETTERDASHNUMBER = '[a-zA-Z0-9-]';
@@ -1393,7 +1403,7 @@ var debug_1 = debug$1;
1393
1403
  createToken('LONETILDE', '(?:~>?)');
1394
1404
 
1395
1405
  createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true);
1396
- exports.tildeTrimReplace = '$1~';
1406
+ exports$1.tildeTrimReplace = '$1~';
1397
1407
 
1398
1408
  createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`);
1399
1409
  createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`);
@@ -1403,7 +1413,7 @@ var debug_1 = debug$1;
1403
1413
  createToken('LONECARET', '(?:\\^)');
1404
1414
 
1405
1415
  createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true);
1406
- exports.caretTrimReplace = '$1^';
1416
+ exports$1.caretTrimReplace = '$1^';
1407
1417
 
1408
1418
  createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`);
1409
1419
  createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`);
@@ -1416,7 +1426,7 @@ var debug_1 = debug$1;
1416
1426
  // it modifies, so that `> 1.2.3` ==> `>1.2.3`
1417
1427
  createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
1418
1428
  }\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true);
1419
- exports.comparatorTrimReplace = '$1$2$3';
1429
+ exports$1.comparatorTrimReplace = '$1$2$3';
1420
1430
 
1421
1431
  // Something like `1.2.3 - 1.2.4`
1422
1432
  // Note that these all use the loose form, because they'll be
@@ -1459,6 +1469,10 @@ var parseOptions_1 = parseOptions$1;
1459
1469
 
1460
1470
  const numeric = /^[0-9]+$/;
1461
1471
  const compareIdentifiers$1 = (a, b) => {
1472
+ if (typeof a === 'number' && typeof b === 'number') {
1473
+ return a === b ? 0 : a < b ? -1 : 1
1474
+ }
1475
+
1462
1476
  const anum = numeric.test(a);
1463
1477
  const bnum = numeric.test(b);
1464
1478
 
@@ -1592,11 +1606,25 @@ let SemVer$d = class SemVer {
1592
1606
  other = new SemVer(other, this.options);
1593
1607
  }
1594
1608
 
1595
- return (
1596
- compareIdentifiers(this.major, other.major) ||
1597
- compareIdentifiers(this.minor, other.minor) ||
1598
- compareIdentifiers(this.patch, other.patch)
1599
- )
1609
+ if (this.major < other.major) {
1610
+ return -1
1611
+ }
1612
+ if (this.major > other.major) {
1613
+ return 1
1614
+ }
1615
+ if (this.minor < other.minor) {
1616
+ return -1
1617
+ }
1618
+ if (this.minor > other.minor) {
1619
+ return 1
1620
+ }
1621
+ if (this.patch < other.patch) {
1622
+ return -1
1623
+ }
1624
+ if (this.patch > other.patch) {
1625
+ return 1
1626
+ }
1627
+ return 0
1600
1628
  }
1601
1629
 
1602
1630
  comparePre (other) {
@@ -2408,6 +2436,7 @@ function requireRange () {
2408
2436
  // already replaced the hyphen ranges
2409
2437
  // turn into a set of JUST comparators.
2410
2438
  const parseComparator = (comp, options) => {
2439
+ comp = comp.replace(re[t.BUILD], '');
2411
2440
  debug('comp', comp, options);
2412
2441
  comp = replaceCarets(comp, options);
2413
2442
  debug('caret', comp);
@@ -5795,20 +5824,78 @@ var jwt = /*@__PURE__*/getDefaultExportFromCjs(jsonwebtoken);
5795
5824
 
5796
5825
  class Mixin {
5797
5826
  createBasicToken(payload, secret, expiresIn, options) {
5798
- const finalOptions = Object.assign(Object.assign({}, (options || {})), { expiresIn });
5827
+ const finalOptions = Object.assign(Object.assign({}, (options || {})), { expiresIn, issuer: (options === null || options === void 0 ? void 0 : options.issuer) || process.env.JWT_ISSUER || 'hemia-app', audience: (options === null || options === void 0 ? void 0 : options.audience) || process.env.JWT_AUDIENCE || 'hemia-api', algorithm: (options === null || options === void 0 ? void 0 : options.algorithm) || 'HS256' });
5799
5828
  return jwt.sign(payload, secret, finalOptions);
5800
5829
  }
5801
- validateTokenBase(token, secretKey) {
5830
+ validateTokenBase(token, secretKey, options) {
5802
5831
  try {
5803
- return jwt.verify(token, secretKey);
5832
+ const verifyOptions = Object.assign(Object.assign({}, options), { algorithms: ['HS256', 'RS256'], issuer: (options === null || options === void 0 ? void 0 : options.issuer) || process.env.JWT_ISSUER, audience: (options === null || options === void 0 ? void 0 : options.audience) || process.env.JWT_AUDIENCE, clockTolerance: 30 });
5833
+ return jwt.verify(token, secretKey, verifyOptions);
5804
5834
  }
5805
5835
  catch (error) {
5806
- console.error('Token inválido:', error);
5836
+ if (error instanceof jwt.TokenExpiredError) {
5837
+ console.error('Token expirado:', error.expiredAt);
5838
+ }
5839
+ else if (error instanceof jwt.JsonWebTokenError) {
5840
+ console.error('Token inválido:', error.message);
5841
+ }
5842
+ else if (error instanceof jwt.NotBeforeError) {
5843
+ console.error('Token no válido aún:', error.date);
5844
+ }
5845
+ else {
5846
+ console.error('Error de validación:', error);
5847
+ }
5807
5848
  return null;
5808
5849
  }
5809
5850
  }
5810
- decodeToken(token) {
5811
- return jwt.decode(token);
5851
+ validateTokenDetailed(token, secretKey, options) {
5852
+ try {
5853
+ const verifyOptions = Object.assign(Object.assign({}, options), { algorithms: ['HS256', 'RS256'], issuer: (options === null || options === void 0 ? void 0 : options.issuer) || process.env.JWT_ISSUER, audience: (options === null || options === void 0 ? void 0 : options.audience) || process.env.JWT_AUDIENCE, clockTolerance: 30 });
5854
+ const payload = jwt.verify(token, secretKey, verifyOptions);
5855
+ return {
5856
+ valid: true,
5857
+ payload
5858
+ };
5859
+ }
5860
+ catch (error) {
5861
+ if (error instanceof jwt.TokenExpiredError) {
5862
+ return {
5863
+ valid: false,
5864
+ error: `Token expirado en: ${error.expiredAt}`,
5865
+ errorType: 'expired'
5866
+ };
5867
+ }
5868
+ else if (error instanceof jwt.JsonWebTokenError) {
5869
+ return {
5870
+ valid: false,
5871
+ error: error.message,
5872
+ errorType: error.message.includes('signature') ? 'signature_invalid' : 'invalid'
5873
+ };
5874
+ }
5875
+ else if (error instanceof jwt.NotBeforeError) {
5876
+ return {
5877
+ valid: false,
5878
+ error: `Token no válido hasta: ${error.date}`,
5879
+ errorType: 'not_before'
5880
+ };
5881
+ }
5882
+ else {
5883
+ return {
5884
+ valid: false,
5885
+ error: 'Error desconocido al validar token',
5886
+ errorType: 'malformed'
5887
+ };
5888
+ }
5889
+ }
5890
+ }
5891
+ decodeToken(token, complete = false) {
5892
+ try {
5893
+ return jwt.decode(token, { complete });
5894
+ }
5895
+ catch (error) {
5896
+ console.error('Error al decodificar token:', error);
5897
+ return null;
5898
+ }
5812
5899
  }
5813
5900
  }
5814
5901
 
@@ -5816,30 +5903,133 @@ class JwtManager extends Mixin {
5816
5903
  constructor() {
5817
5904
  super();
5818
5905
  this._secretKey = '';
5906
+ this._issuer = '';
5907
+ this._audience = '';
5819
5908
  this._secretKey = process.env.JWT_SECRET || jwtConfig.cleanCredentialSecret;
5909
+ this._issuer = process.env.JWT_ISSUER || 'hemia-app';
5910
+ this._audience = process.env.JWT_AUDIENCE || 'hemia-api';
5820
5911
  if (!this._secretKey) {
5821
5912
  throw new Error("JWT secret key is required.");
5822
5913
  }
5823
5914
  }
5915
+ createToken(payload, expiresIn, options) {
5916
+ return this.createBasicToken(payload, this._secretKey, expiresIn || jwtConfig.expiresIn, Object.assign(Object.assign({}, options), { issuer: (options === null || options === void 0 ? void 0 : options.issuer) || this._issuer, audience: (options === null || options === void 0 ? void 0 : options.audience) || this._audience }));
5917
+ }
5918
+ createTokenWithSecret(payload, secretKey, expiresIn, options) {
5919
+ return this.createBasicToken(payload, secretKey, expiresIn || jwtConfig.expiresIn, Object.assign(Object.assign({}, options), { issuer: (options === null || options === void 0 ? void 0 : options.issuer) || this._issuer, audience: (options === null || options === void 0 ? void 0 : options.audience) || this._audience }));
5920
+ }
5921
+ createCleanCredentialsToken(operative = Operatives.CATALOG, expiresIn) {
5922
+ const payload = { accessType: operative };
5923
+ return this.createBasicToken(payload, this._secretKey, expiresIn || jwtConfig.expiresIn);
5924
+ }
5824
5925
  getTokenWithoutKey(payload, expiresIn, options) {
5825
- return this.createBasicToken(payload, this._secretKey, expiresIn || jwtConfig.expiresIn, options);
5926
+ return this.createToken(payload, expiresIn, options);
5826
5927
  }
5827
5928
  getTokenWithKey(payload, secretKey, expiresIn, options) {
5828
- return this.createBasicToken(payload, secretKey, expiresIn || jwtConfig.expiresIn, options);
5929
+ return this.createTokenWithSecret(payload, secretKey, expiresIn, options);
5829
5930
  }
5830
5931
  getTokenCleanCredentials(operative = Operatives.CATALOG, expiresIn) {
5831
- const payload = { accessType: operative };
5832
- return this.createBasicToken(payload, this._secretKey, expiresIn || jwtConfig.expiresIn);
5932
+ return this.createCleanCredentialsToken(operative, expiresIn);
5833
5933
  }
5834
- validateToken(token, secretKey) {
5835
- return this.validateTokenBase(token, secretKey || this._secretKey);
5934
+ createIdToken(claims, expiresIn) {
5935
+ if (!claims.sub) {
5936
+ throw new Error('sub (subject) claim is required for ID tokens');
5937
+ }
5938
+ const payload = Object.assign(Object.assign({}, claims), { iss: this._issuer, aud: this._audience, iat: Math.floor(Date.now() / 1000) });
5939
+ return this.createBasicToken(payload, this._secretKey, expiresIn || jwtConfig.expiresIn, { issuer: this._issuer, audience: this._audience });
5836
5940
  }
5837
- decode(token) {
5838
- return this.decodeToken(token);
5941
+ createAccessToken(sub, scopes, expiresIn) {
5942
+ const payload = {
5943
+ sub,
5944
+ scope: scopes.join(' '),
5945
+ iss: this._issuer,
5946
+ aud: this._audience,
5947
+ iat: Math.floor(Date.now() / 1000),
5948
+ };
5949
+ return this.createBasicToken(payload, this._secretKey, expiresIn || '15m', { issuer: this._issuer, audience: this._audience });
5950
+ }
5951
+ createRefreshToken(sub, expiresIn) {
5952
+ const payload = {
5953
+ sub,
5954
+ type: 'refresh',
5955
+ iss: this._issuer,
5956
+ aud: this._audience,
5957
+ iat: Math.floor(Date.now() / 1000),
5958
+ };
5959
+ return this.createBasicToken(payload, this._secretKey, expiresIn || '30d', {
5960
+ issuer: this._issuer,
5961
+ audience: this._audience,
5962
+ jwtid: this.generateJti()
5963
+ });
5964
+ }
5965
+ verify(token, secretKey, options) {
5966
+ return this.validateTokenBase(token, secretKey || this._secretKey, Object.assign(Object.assign({}, options), { issuer: (options === null || options === void 0 ? void 0 : options.issuer) || this._issuer, audience: (options === null || options === void 0 ? void 0 : options.audience) || this._audience }));
5967
+ }
5968
+ verifyDetailed(token, secretKey, options) {
5969
+ return super.validateTokenDetailed(token, secretKey || this._secretKey, Object.assign(Object.assign({}, options), { issuer: (options === null || options === void 0 ? void 0 : options.issuer) || this._issuer, audience: (options === null || options === void 0 ? void 0 : options.audience) || this._audience }));
5970
+ }
5971
+ validateToken(token, secretKey, options) {
5972
+ return this.verify(token, secretKey, options);
5973
+ }
5974
+ validateTokenDetailed(token, secretKey, options) {
5975
+ return this.verifyDetailed(token, secretKey, options);
5976
+ }
5977
+ decode(token, complete = false) {
5978
+ return this.decodeToken(token, complete);
5979
+ }
5980
+ getClaims(token) {
5981
+ const decoded = this.decodeToken(token);
5982
+ if (!decoded)
5983
+ return null;
5984
+ const { sub, name, given_name, family_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, updated_at, email, email_verified, phone_number, phone_number_verified, address } = decoded;
5985
+ return {
5986
+ sub,
5987
+ name,
5988
+ given_name,
5989
+ family_name,
5990
+ middle_name,
5991
+ nickname,
5992
+ preferred_username,
5993
+ profile,
5994
+ picture,
5995
+ website,
5996
+ gender,
5997
+ birthdate,
5998
+ zoneinfo,
5999
+ locale,
6000
+ updated_at,
6001
+ email,
6002
+ email_verified,
6003
+ phone_number,
6004
+ phone_number_verified,
6005
+ address
6006
+ };
6007
+ }
6008
+ getStandardClaims(token) {
6009
+ return this.getClaims(token);
6010
+ }
6011
+ hasScope(token, requiredScope) {
6012
+ const payload = this.verify(token);
6013
+ if (!payload || !payload.scope)
6014
+ return false;
6015
+ const scopes = typeof payload.scope === 'string'
6016
+ ? payload.scope.split(' ')
6017
+ : [];
6018
+ return scopes.includes(requiredScope);
6019
+ }
6020
+ generateJti() {
6021
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
5839
6022
  }
5840
6023
  getJwtKey() {
5841
6024
  return this._secretKey;
5842
6025
  }
5843
6026
  }
5844
6027
 
5845
- export { JwtManager, Operatives };
6028
+ var TokenType;
6029
+ (function (TokenType) {
6030
+ TokenType["ID_TOKEN"] = "id_token";
6031
+ TokenType["ACCESS_TOKEN"] = "access_token";
6032
+ TokenType["REFRESH_TOKEN"] = "refresh_token";
6033
+ })(TokenType || (TokenType = {}));
6034
+
6035
+ export { JwtManager, Operatives, TokenType };