eslint-plugin-jwt-security 3.5.1 → 3.5.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-jwt-security",
3
- "version": "3.5.1",
3
+ "version": "3.5.2",
4
4
  "description": "ESLint plugin for JWT security — detects algorithm confusion (CVE-2022-23540), alg:none, weak or hardcoded secrets, and decode-without-verify.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
package/src/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noSensitivePayload=exports.requireMaxAge=exports.noTimestampManipulation=exports.requireAudienceValidation=exports.requireIssuerValidation=exports.requireIssuedAt=exports.noHardcodedSecret=exports.requireExpiration=exports.noWeakSecret=exports.noDecodeWithoutVerify=exports.requireAlgorithmWhitelist=exports.noAlgorithmConfusion=exports.noAlgorithmNone=exports.configs=exports.plugin=exports.rules=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const no_algorithm_none_1=require("./rules/no-algorithm-none");Object.defineProperty(exports,"noAlgorithmNone",{enumerable:true,get:function(){return no_algorithm_none_1.noAlgorithmNone}});const no_algorithm_confusion_1=require("./rules/no-algorithm-confusion");Object.defineProperty(exports,"noAlgorithmConfusion",{enumerable:true,get:function(){return no_algorithm_confusion_1.noAlgorithmConfusion}});const require_algorithm_whitelist_1=require("./rules/require-algorithm-whitelist");Object.defineProperty(exports,"requireAlgorithmWhitelist",{enumerable:true,get:function(){return require_algorithm_whitelist_1.requireAlgorithmWhitelist}});const no_decode_without_verify_1=require("./rules/no-decode-without-verify");Object.defineProperty(exports,"noDecodeWithoutVerify",{enumerable:true,get:function(){return no_decode_without_verify_1.noDecodeWithoutVerify}});const no_weak_secret_1=require("./rules/no-weak-secret");Object.defineProperty(exports,"noWeakSecret",{enumerable:true,get:function(){return no_weak_secret_1.noWeakSecret}});const require_expiration_1=require("./rules/require-expiration");Object.defineProperty(exports,"requireExpiration",{enumerable:true,get:function(){return require_expiration_1.requireExpiration}});const no_hardcoded_secret_1=require("./rules/no-hardcoded-secret");Object.defineProperty(exports,"noHardcodedSecret",{enumerable:true,get:function(){return no_hardcoded_secret_1.noHardcodedSecret}});const require_issued_at_1=require("./rules/require-issued-at");Object.defineProperty(exports,"requireIssuedAt",{enumerable:true,get:function(){return require_issued_at_1.requireIssuedAt}});const require_issuer_validation_1=require("./rules/require-issuer-validation");Object.defineProperty(exports,"requireIssuerValidation",{enumerable:true,get:function(){return require_issuer_validation_1.requireIssuerValidation}});const require_audience_validation_1=require("./rules/require-audience-validation");Object.defineProperty(exports,"requireAudienceValidation",{enumerable:true,get:function(){return require_audience_validation_1.requireAudienceValidation}});const no_timestamp_manipulation_1=require("./rules/no-timestamp-manipulation");Object.defineProperty(exports,"noTimestampManipulation",{enumerable:true,get:function(){return no_timestamp_manipulation_1.noTimestampManipulation}});const require_max_age_1=require("./rules/require-max-age");Object.defineProperty(exports,"requireMaxAge",{enumerable:true,get:function(){return require_max_age_1.requireMaxAge}});const no_sensitive_payload_1=require("./rules/no-sensitive-payload");Object.defineProperty(exports,"noSensitivePayload",{enumerable:true,get:function(){return no_sensitive_payload_1.noSensitivePayload}});exports.rules={get"no-algorithm-none"(){return require("./rules/no-algorithm-none").noAlgorithmNone},get"no-algorithm-confusion"(){return require("./rules/no-algorithm-confusion").noAlgorithmConfusion},get"require-algorithm-whitelist"(){return require("./rules/require-algorithm-whitelist").requireAlgorithmWhitelist},get"no-decode-without-verify"(){return require("./rules/no-decode-without-verify").noDecodeWithoutVerify},get"no-weak-secret"(){return require("./rules/no-weak-secret").noWeakSecret},get"require-expiration"(){return require("./rules/require-expiration").requireExpiration},get"no-hardcoded-secret"(){return require("./rules/no-hardcoded-secret").noHardcodedSecret},get"require-issued-at"(){return require("./rules/require-issued-at").requireIssuedAt},get"require-issuer-validation"(){return require("./rules/require-issuer-validation").requireIssuerValidation},get"require-audience-validation"(){return require("./rules/require-audience-validation").requireAudienceValidation},get"no-timestamp-manipulation"(){return require("./rules/no-timestamp-manipulation").noTimestampManipulation},get"require-max-age"(){return require("./rules/require-max-age").requireMaxAge},get"no-sensitive-payload"(){return require("./rules/no-sensitive-payload").noSensitivePayload}};(0,eslint_devkit_1.withCanonicalDocsUrls)("plugin-jwt-security",exports.rules);exports.plugin={meta:{name:"eslint-plugin-jwt-security",version:"3.5.1"},rules:exports.rules};const recommendedRules={"jwt-security/no-algorithm-none":"error","jwt-security/no-algorithm-confusion":"error","jwt-security/require-algorithm-whitelist":"error","jwt-security/no-decode-without-verify":"error","jwt-security/no-weak-secret":"error","jwt-security/no-hardcoded-secret":"error","jwt-security/no-timestamp-manipulation":"error","jwt-security/require-expiration":"error","jwt-security/no-sensitive-payload":"warn","jwt-security/require-issued-at":"warn"};const strictRules={"jwt-security/no-algorithm-none":"error","jwt-security/no-algorithm-confusion":"error","jwt-security/require-algorithm-whitelist":"error","jwt-security/no-decode-without-verify":"error","jwt-security/no-weak-secret":"error","jwt-security/no-hardcoded-secret":"error","jwt-security/require-expiration":"error","jwt-security/require-issued-at":"error","jwt-security/require-issuer-validation":"error","jwt-security/require-audience-validation":"error","jwt-security/no-timestamp-manipulation":"error","jwt-security/require-max-age":"error","jwt-security/no-sensitive-payload":"error"};const legacyRules={"jwt-security/no-algorithm-none":"error","jwt-security/no-algorithm-confusion":"error","jwt-security/no-hardcoded-secret":"warn"};exports.configs={flagship:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:{"jwt-security/no-algorithm-none":"error"}},recommended:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:recommendedRules},strict:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:strictRules},legacy:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:legacyRules},all:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:strictRules}};exports.default=exports.plugin;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noSensitivePayload=exports.requireMaxAge=exports.noTimestampManipulation=exports.requireAudienceValidation=exports.requireIssuerValidation=exports.requireIssuedAt=exports.noHardcodedSecret=exports.requireExpiration=exports.noWeakSecret=exports.noDecodeWithoutVerify=exports.requireAlgorithmWhitelist=exports.noAlgorithmConfusion=exports.noAlgorithmNone=exports.configs=exports.plugin=exports.rules=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const no_algorithm_none_1=require("./rules/no-algorithm-none");Object.defineProperty(exports,"noAlgorithmNone",{enumerable:true,get:function(){return no_algorithm_none_1.noAlgorithmNone}});const no_algorithm_confusion_1=require("./rules/no-algorithm-confusion");Object.defineProperty(exports,"noAlgorithmConfusion",{enumerable:true,get:function(){return no_algorithm_confusion_1.noAlgorithmConfusion}});const require_algorithm_whitelist_1=require("./rules/require-algorithm-whitelist");Object.defineProperty(exports,"requireAlgorithmWhitelist",{enumerable:true,get:function(){return require_algorithm_whitelist_1.requireAlgorithmWhitelist}});const no_decode_without_verify_1=require("./rules/no-decode-without-verify");Object.defineProperty(exports,"noDecodeWithoutVerify",{enumerable:true,get:function(){return no_decode_without_verify_1.noDecodeWithoutVerify}});const no_weak_secret_1=require("./rules/no-weak-secret");Object.defineProperty(exports,"noWeakSecret",{enumerable:true,get:function(){return no_weak_secret_1.noWeakSecret}});const require_expiration_1=require("./rules/require-expiration");Object.defineProperty(exports,"requireExpiration",{enumerable:true,get:function(){return require_expiration_1.requireExpiration}});const no_hardcoded_secret_1=require("./rules/no-hardcoded-secret");Object.defineProperty(exports,"noHardcodedSecret",{enumerable:true,get:function(){return no_hardcoded_secret_1.noHardcodedSecret}});const require_issued_at_1=require("./rules/require-issued-at");Object.defineProperty(exports,"requireIssuedAt",{enumerable:true,get:function(){return require_issued_at_1.requireIssuedAt}});const require_issuer_validation_1=require("./rules/require-issuer-validation");Object.defineProperty(exports,"requireIssuerValidation",{enumerable:true,get:function(){return require_issuer_validation_1.requireIssuerValidation}});const require_audience_validation_1=require("./rules/require-audience-validation");Object.defineProperty(exports,"requireAudienceValidation",{enumerable:true,get:function(){return require_audience_validation_1.requireAudienceValidation}});const no_timestamp_manipulation_1=require("./rules/no-timestamp-manipulation");Object.defineProperty(exports,"noTimestampManipulation",{enumerable:true,get:function(){return no_timestamp_manipulation_1.noTimestampManipulation}});const require_max_age_1=require("./rules/require-max-age");Object.defineProperty(exports,"requireMaxAge",{enumerable:true,get:function(){return require_max_age_1.requireMaxAge}});const no_sensitive_payload_1=require("./rules/no-sensitive-payload");Object.defineProperty(exports,"noSensitivePayload",{enumerable:true,get:function(){return no_sensitive_payload_1.noSensitivePayload}});exports.rules={get"no-algorithm-none"(){return require("./rules/no-algorithm-none").noAlgorithmNone},get"no-algorithm-confusion"(){return require("./rules/no-algorithm-confusion").noAlgorithmConfusion},get"require-algorithm-whitelist"(){return require("./rules/require-algorithm-whitelist").requireAlgorithmWhitelist},get"no-decode-without-verify"(){return require("./rules/no-decode-without-verify").noDecodeWithoutVerify},get"no-weak-secret"(){return require("./rules/no-weak-secret").noWeakSecret},get"require-expiration"(){return require("./rules/require-expiration").requireExpiration},get"no-hardcoded-secret"(){return require("./rules/no-hardcoded-secret").noHardcodedSecret},get"require-issued-at"(){return require("./rules/require-issued-at").requireIssuedAt},get"require-issuer-validation"(){return require("./rules/require-issuer-validation").requireIssuerValidation},get"require-audience-validation"(){return require("./rules/require-audience-validation").requireAudienceValidation},get"no-timestamp-manipulation"(){return require("./rules/no-timestamp-manipulation").noTimestampManipulation},get"require-max-age"(){return require("./rules/require-max-age").requireMaxAge},get"no-sensitive-payload"(){return require("./rules/no-sensitive-payload").noSensitivePayload}};(0,eslint_devkit_1.withCanonicalDocsUrls)("plugin-jwt-security",exports.rules);exports.plugin={meta:{name:"eslint-plugin-jwt-security",version:"3.5.2"},rules:exports.rules};const recommendedRules={"jwt-security/no-algorithm-none":"error","jwt-security/no-algorithm-confusion":"error","jwt-security/require-algorithm-whitelist":"error","jwt-security/no-decode-without-verify":"error","jwt-security/no-weak-secret":"error","jwt-security/no-hardcoded-secret":"error","jwt-security/no-timestamp-manipulation":"error","jwt-security/require-expiration":"error","jwt-security/no-sensitive-payload":"warn","jwt-security/require-issued-at":"warn"};const strictRules={"jwt-security/no-algorithm-none":"error","jwt-security/no-algorithm-confusion":"error","jwt-security/require-algorithm-whitelist":"error","jwt-security/no-decode-without-verify":"error","jwt-security/no-weak-secret":"error","jwt-security/no-hardcoded-secret":"error","jwt-security/require-expiration":"error","jwt-security/require-issued-at":"error","jwt-security/require-issuer-validation":"error","jwt-security/require-audience-validation":"error","jwt-security/no-timestamp-manipulation":"error","jwt-security/require-max-age":"error","jwt-security/no-sensitive-payload":"error"};const legacyRules={"jwt-security/no-algorithm-none":"error","jwt-security/no-algorithm-confusion":"error","jwt-security/no-hardcoded-secret":"warn"};exports.configs={flagship:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:{"jwt-security/no-algorithm-none":"error"}},recommended:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:recommendedRules},strict:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:strictRules},legacy:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:legacyRules},all:{plugins:{"jwt-security":exports.plugin,jwt:exports.plugin},rules:strictRules}};exports.default=exports.plugin;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireExpiration=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const utils_1=require("../../utils");const nest_modules_1=require("../../utils/nest-modules");exports.requireExpiration=(0,eslint_devkit_1.createRule)({name:"require-expiration",skipTestFiles:true,meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-expiration.md",description:"Require expiration claim (exp) or expiresIn option in JWT signing",cwe:"CWE-613",cvss:5.4},hasSuggestions:true,messages:{missingExpiration:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Missing JWT Expiration",cwe:"CWE-613",description:"JWT without expiration is valid forever, increasing exposure window",severity:"MEDIUM",fix:'Add expiresIn: "1h" or exp claim to payload',documentationLink:"https://tools.ietf.org/html/rfc8725"}),addExpiration:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Expiration",description:"Add expiration to limit token lifetime",severity:"LOW",fix:'jwt.sign(payload, secret, { expiresIn: "1h" })',documentationLink:"https://www.npmjs.com/package/jsonwebtoken"})},schema:[{type:"object",properties:{maxExpirationSeconds:{type:"integer",default:86400,description:"Maximum allowed expiration time in seconds (24h default)"},trustedSanitizers:{type:"array",items:{type:"string"},default:[]},trustedAnnotations:{type:"array",items:{type:"string"},default:[]},strictMode:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{maxExpirationSeconds:86400,trustedSanitizers:[],trustedAnnotations:[],strictMode:false}],create(context){const payloadHasExp=payloadNode=>{const resolved=payloadNode.type==="Identifier"?resolveObjectLiteral(payloadNode):payloadNode;if(resolved===null||resolved.type!=="ObjectExpression"){return false}return(0,utils_1.hasOption)(resolved,"exp")};const resolveObjectLiteral=node=>{let variable=null;let scope=context.sourceCode.getScope(node);while(scope!==null&&variable===null){variable=scope.variables.find(candidate=>candidate.name===node.name)??null;scope=scope.upper}if(variable===null||variable.defs.length!==1){return null}const definition=variable.defs[0];return definition.type==="Variable"?definition.node.init??null:null};const sourceCode=context.sourceCode;const JWS_ONLY_BUILDERS=new Set(["FlattenedSign","CompactSign","GeneralSign"]);return{CallExpression(node){if(!(0,utils_1.isSignOperation)(node,sourceCode)){return}if(node.arguments.length<1){return}const chain=(0,utils_1.joseBuilderChain)(node,sourceCode);if(chain!==null){if(JWS_ONLY_BUILDERS.has(chain.kind)||chain.calls.has("setExpirationTime")){return}const claims=chain.builder.arguments[0];if(claims!==void 0&&payloadHasExp(claims)){return}}else{const payloadArg=node.arguments[0];if(payloadHasExp(payloadArg)){return}const nestShaped=(0,utils_1.isNestJwtShape)(node,sourceCode)||node.arguments.length===1&&node.callee.type===eslint_devkit_1.AST_NODE_TYPES.MemberExpression&&node.callee.object.type!==eslint_devkit_1.AST_NODE_TYPES.CallExpression&&node.callee.object.type!==eslint_devkit_1.AST_NODE_TYPES.NewExpression;if(nestShaped){const own=(0,utils_1.resolveObject)(node.arguments[1],sourceCode);if(own!==null&&((0,utils_1.hasOption)(own,"expiresIn")||own.opaque)||(0,nest_modules_1.nestModuleExpiry)(context.filename,context.languageOptions.parser)!=="missing"){return}}else{const options=(0,utils_1.resolveCallOptions)(node,sourceCode);if(options!==null&&((0,utils_1.hasOption)(options,"expiresIn")||options.opaque)){return}}}const optionsArg3=node.arguments[(0,utils_1.isNestJwtShape)(node,sourceCode)?1:2];context.report({node,messageId:"missingExpiration",suggest:[{messageId:"addExpiration",fix(fixer){const sourceCode2=context.sourceCode;if(optionsArg3&&optionsArg3.type===eslint_devkit_1.AST_NODE_TYPES.ObjectExpression){const openBrace=sourceCode2.getFirstToken(optionsArg3);return fixer.insertTextAfter(openBrace," expiresIn: '1h',")}const lastArg=node.arguments[node.arguments.length-1];return fixer.insertTextAfter(lastArg,", { expiresIn: '1h' }")}}]})}}}});exports.default=exports.requireExpiration;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireExpiration=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const utils_1=require("../../utils");const lifetime_1=require("../../utils/lifetime");const nest_modules_1=require("../../utils/nest-modules");exports.requireExpiration=(0,eslint_devkit_1.createRule)({name:"require-expiration",skipTestFiles:true,meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-expiration.md",description:"Require expiration claim (exp) or expiresIn option in JWT signing",cwe:"CWE-613",cvss:5.4},hasSuggestions:true,messages:{missingExpiration:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Missing JWT Expiration",cwe:"CWE-613",description:"JWT without expiration is valid forever, increasing exposure window",severity:"MEDIUM",fix:'Add expiresIn: "1h" or exp claim to payload',documentationLink:"https://tools.ietf.org/html/rfc8725"}),excessiveExpiration:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Excessive JWT Expiration",cwe:"CWE-613",description:"JWT lives {{seconds}}s, longer than the configured maxExpirationSeconds ({{max}}s)",severity:"MEDIUM",fix:"Shorten expiresIn / exp to at most {{max}} seconds, and use a refresh token for longer sessions",documentationLink:"https://tools.ietf.org/html/rfc8725"}),addExpiration:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Expiration",description:"Add expiration to limit token lifetime",severity:"LOW",fix:'jwt.sign(payload, secret, { expiresIn: "1h" })',documentationLink:"https://www.npmjs.com/package/jsonwebtoken"})},schema:[{type:"object",properties:{maxExpirationSeconds:{type:"integer",description:"Maximum allowed token lifetime in seconds. Unset (the default) enforces no limit."},trustedSanitizers:{type:"array",items:{type:"string"},default:[]},trustedAnnotations:{type:"array",items:{type:"string"},default:[]},strictMode:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{trustedSanitizers:[],trustedAnnotations:[],strictMode:false}],create(context){const maxExpirationSeconds=context.options[0]?.maxExpirationSeconds;const checkLifetime=(node,seconds)=>{if(maxExpirationSeconds===void 0||seconds===null||seconds<=maxExpirationSeconds){return}context.report({node,messageId:"excessiveExpiration",data:{seconds:String(seconds),max:String(maxExpirationSeconds)}})};const optionsLifetime=options=>(0,lifetime_1.expiresInSeconds)((0,utils_1.getOptionValue)(options,"expiresIn"),sourceCode);const payloadHasExp=payloadNode=>{const resolved=resolvePayload(payloadNode);if(resolved===null||resolved.type!=="ObjectExpression"){return false}return(0,utils_1.hasOption)(resolved,"exp")};const resolvePayload=payloadNode=>payloadNode.type==="Identifier"?resolveObjectLiteral(payloadNode):payloadNode;const resolveObjectLiteral=node=>{let variable=null;let scope=context.sourceCode.getScope(node);while(scope!==null&&variable===null){variable=scope.variables.find(candidate=>candidate.name===node.name)??null;scope=scope.upper}if(variable===null||variable.defs.length!==1){return null}const definition=variable.defs[0];return definition.type==="Variable"?definition.node.init??null:null};const sourceCode=context.sourceCode;const JWS_ONLY_BUILDERS=new Set(["FlattenedSign","CompactSign","GeneralSign"]);return{CallExpression(node){if(!(0,utils_1.isSignOperation)(node,sourceCode)){return}if(node.arguments.length<1){return}const chain=(0,utils_1.joseBuilderChain)(node,sourceCode);if(chain!==null){if(JWS_ONLY_BUILDERS.has(chain.kind)||chain.calls.has("setExpirationTime")){return}const claims=chain.builder.arguments[0];if(claims!==void 0&&payloadHasExp(claims)){return}}else{const payloadArg=node.arguments[0];if(payloadHasExp(payloadArg)){const exp=(0,utils_1.getOptionValue)(resolvePayload(payloadArg),"exp");checkLifetime(node,(0,lifetime_1.expClaimSeconds)(exp,sourceCode));return}const nestShaped=(0,utils_1.isNestJwtShape)(node,sourceCode)||node.arguments.length===1&&node.callee.type===eslint_devkit_1.AST_NODE_TYPES.MemberExpression&&node.callee.object.type!==eslint_devkit_1.AST_NODE_TYPES.CallExpression&&node.callee.object.type!==eslint_devkit_1.AST_NODE_TYPES.NewExpression;if(nestShaped){const own=(0,utils_1.resolveObject)(node.arguments[1],sourceCode);if(own!==null&&(0,utils_1.hasOption)(own,"expiresIn")){checkLifetime(node,optionsLifetime(own));return}if(own?.opaque===true||(0,nest_modules_1.nestModuleExpiry)(context.filename,context.languageOptions.parser)!=="missing"){return}}else{const options=(0,utils_1.resolveCallOptions)(node,sourceCode);if(options!==null&&(0,utils_1.hasOption)(options,"expiresIn")){checkLifetime(node,optionsLifetime(options));return}if(options?.opaque===true){return}}}const optionsArg3=node.arguments[(0,utils_1.isNestJwtShape)(node,sourceCode)?1:2];context.report({node,messageId:"missingExpiration",suggest:[{messageId:"addExpiration",fix(fixer){const sourceCode2=context.sourceCode;if(optionsArg3&&optionsArg3.type===eslint_devkit_1.AST_NODE_TYPES.ObjectExpression){const openBrace=sourceCode2.getFirstToken(optionsArg3);return fixer.insertTextAfter(openBrace," expiresIn: '1h',")}const lastArg=node.arguments[node.arguments.length-1];return fixer.insertTextAfter(lastArg,", { expiresIn: '1h' }")}}]})}}}});exports.default=exports.requireExpiration;
@@ -38,7 +38,7 @@ export interface NoWeakSecretOptions extends JwtRuleOptions {
38
38
  minSecretLength?: number;
39
39
  }
40
40
  export interface RequireExpirationOptions extends JwtRuleOptions {
41
- /** Maximum allowed expiration time in seconds. Default: 86400 (24 hours) */
41
+ /** Longest token lifetime allowed, in seconds. Unset (the default) enforces no limit. */
42
42
  maxExpirationSeconds?: number;
43
43
  }
44
44
  export interface RequireIssuerValidationOptions extends JwtRuleOptions {
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.msStringSeconds=msStringSeconds;exports.expiresInSeconds=expiresInSeconds;exports.expClaimSeconds=expClaimSeconds;const eslint_devkit_1=require("@interlace/eslint-devkit");const value_flow_1=require("./value-flow");const UNIT_SECONDS=new Map([...["years","year","yrs","yr","y"].map(u=>[u,31557600]),...["weeks","week","w"].map(u=>[u,604800]),...["days","day","d"].map(u=>[u,86400]),...["hours","hour","hrs","hr","h"].map(u=>[u,3600]),...["minutes","minute","mins","min","m"].map(u=>[u,60]),...["seconds","second","secs","sec","s"].map(u=>[u,1]),...["milliseconds","millisecond","msecs","msec","ms"].map(u=>[u,.001])]);const MS_STRING=/^(-?(?:\d+)?\.?\d+) *([a-z]*)$/i;function msStringSeconds(text){const match=MS_STRING.exec(text);if(match===null)return null;const unit=match[2].toLowerCase();const perUnit=unit===""?.001:UNIT_SECONDS.get(unit);return perUnit===void 0?null:Number(match[1])*perUnit}function expiresInSeconds(node,sourceCode){const text=(0,eslint_devkit_1.staticString)((0,value_flow_1.resolveTerminal)(node,sourceCode));return text===null?(0,value_flow_1.staticNumber)(node,sourceCode):msStringSeconds(text)}const ROUNDING=new Set(["Math.floor","Math.round","Math.trunc","Math.ceil"]);function calleeName(node){return(0,eslint_devkit_1.memberPath)(node.callee)?.join(".")??null}function isNowInSeconds(node,sourceCode){const value=(0,value_flow_1.resolveTerminal)(node,sourceCode);if(value.type===eslint_devkit_1.AST_NODE_TYPES.CallExpression&&ROUNDING.has(calleeName(value))&&value.arguments.length===1){return isNowInSeconds(value.arguments[0],sourceCode)}return value.type===eslint_devkit_1.AST_NODE_TYPES.BinaryExpression&&value.operator==="/"&&(0,value_flow_1.staticNumber)(value.right,sourceCode)===1e3&&value.left.type===eslint_devkit_1.AST_NODE_TYPES.CallExpression&&calleeName(value.left)==="Date.now"}function expClaimSeconds(node,sourceCode){const value=(0,value_flow_1.resolveTerminal)(node,sourceCode);if(value.type!==eslint_devkit_1.AST_NODE_TYPES.BinaryExpression||value.operator!=="+"){return null}if(isNowInSeconds(value.left,sourceCode)){return(0,value_flow_1.staticNumber)(value.right,sourceCode)}return isNowInSeconds(value.right,sourceCode)?(0,value_flow_1.staticNumber)(value.left,sourceCode):null}