diff --git a/packages/imperative/CHANGELOG.md b/packages/imperative/CHANGELOG.md index 96bf69470a..4ea8649f58 100644 --- a/packages/imperative/CHANGELOG.md +++ b/packages/imperative/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to the Imperative package will be documented in this file. +## Recent Changes + +- Enhancement: Use the new SDK method `ConfigUtils.hasTokenExpired` to check whether a given JSON web token has expired. [#2298](https://github.com/zowe/zowe-cli/pull/2298) +- Enhancement: Use the new SDK method `ProfileInfo.hasTokenExpiredForProfile` to check whether the JSON web token has expired for a specified profile. [#2298](https://github.com/zowe/zowe-cli/pull/2298) + ## `8.1.2` - BugFix: Fixed issues flagged by Coverity [#2291](https://github.com/zowe/zowe-cli/pull/2291) @@ -24,16 +29,17 @@ All notable changes to the Imperative package will be documented in this file. - Update: Final prerelease - Update: See `5.27.1` for details - ## `8.0.0-next.202408301809` - LTS Breaking: Removed the following obsolete V1 profile classes/functions: + - `CliProfileManager` - `CliUtils.getOptValueFromProfiles` - `CommandProfiles` - `ProfileValidator` See [`8.0.0-next.202408271330`](#800-next202408271330) for replacements + - Next Breaking: Changed 2nd parameter of `CliUtils.getOptValuesFromConfig` method from type `ICommandDefinition` to `ICommandProfile`. - Next Breaking: Renamed `ConfigSecure.secureFieldsForLayer` method to `securePropsForLayer`. @@ -213,6 +219,7 @@ All notable changes to the Imperative package will be documented in this file. - BugFix: Updated debugging output for technical currency. [#2100](https://github.com/zowe/zowe-cli/pull/2100) ## `8.0.0-next.202403141949` + - LTS Breaking: Modified the @zowe/imperative SDK [#1703](https://github.com/zowe/zowe-cli/issues/1703) - Renamed class ProfileIO to V1ProfileConversion. - Removed the following obsolete V1 profile functions: @@ -247,8 +254,11 @@ All notable changes to the Imperative package will be documented in this file. - Enhancement: Replaced the term "Team configuration" with "Zowe client configuration" in the `zowe config report-env` command. - LTS Breaking: [#1703](https://github.com/zowe/zowe-cli/issues/1703) + - Removed the following obsolete V1 profile interfaces: + - @zowe/cli-test-utils + - ISetupEnvironmentParms.createOldProfiles - @zowe/imperative @@ -277,16 +287,20 @@ All notable changes to the Imperative package will be documented in this file. - IValidateProfileWithSchema - Removed the following obsolete V1 profile classes/functions: + - @zowe/core-for-zowe-sdk + - File ProfileUtils.ts, which includes these functions: - getDefaultProfile - getZoweDir - moved to ProfileInfo.getZoweDir - @zowe/cli-test-utils + - TempTestProfiles.forceOldProfiles - TestUtils.stripProfileDeprecationMessages - @zowe/imperative + - AbstractProfileManager - Any remaining functions consolidated into CliProfileManager - AbstractProfileManagerFactory @@ -336,10 +350,11 @@ All notable changes to the Imperative package will be documented in this file. - To detect if only V1 profiles exist, use ProfileInfo.onlyV1ProfilesExist - @zowe/zos-uss-for-zowe-sdk - - SshBaseHandler - - Removed the unused, protected property ‘mSshProfile’ + - SshBaseHandler + - Removed the unused, protected property ‘mSshProfile’ - Removed the following obsolete V1 profile constants: + - @zowe/imperative - CoreMessages class - createProfileCommandSummary @@ -447,7 +462,6 @@ All notable changes to the Imperative package will be documented in this file. - Enhancement: Added `name-only` alias to `root` on `config list` command [#1797](https://github.com/zowe/zowe-cli/issues/1797) - BugFix: Resolved technical currency by updating `socks` transitive dependency - ## `8.0.0-next.202401191954` - LTS Breaking: Removed the following: @@ -659,8 +673,8 @@ All notable changes to the Imperative package will be documented in this file. - Enhancement: Added the function IO.giveAccessOnlyToOwner to restrict access to only the currently running user ID. - Enhancement: Enable command arguments to change `{$Prefix}_EDITOR`. Updating IDiffOptions -to include names for the files that are to be compared. Updating IO.getDefaultTextEditor() for different os versions. Updating return value types for `CliUtils.readPrompt`. Changes made to support recent zowe cli work: -[zowe-cli#1672](https://github.com/zowe/zowe-cli/pull/1672) + to include names for the files that are to be compared. Updating IO.getDefaultTextEditor() for different os versions. Updating return value types for `CliUtils.readPrompt`. Changes made to support recent zowe cli work: + [zowe-cli#1672](https://github.com/zowe/zowe-cli/pull/1672) ## `5.13.2` @@ -881,7 +895,7 @@ to include names for the files that are to be compared. Updating IO.getDefaultTe ## `5.1.0` - Enhancement: Introduced flag `--show-inputs-only` to show the inputs of the command -that would be used if a command were executed. + that would be used if a command were executed. - Enhancement: Added dark theme to web help that is automatically used when system-wide dark mode is enabled. - BugFix: Fixed ProfileInfo API `argTeamConfigLoc` not recognizing secure fields in multi-layer operations. [#800](https://github.com/zowe/imperative/pull/800) - BugFix: Fixed ProfileInfo API `updateKnownProperty` possibly storing information in the wrong location due to optional osLoc information. [#800](https://github.com/zowe/imperative/pull/800) @@ -996,8 +1010,8 @@ that would be used if a command were executed. - Enhancement: Replaced hidden `--dcd` option used by CommandProcessor in daemon mode with IDaemonResponse object. - **Next Breaking** - - Changed the "args" type on the `Imperative.parse` method to allow a string array. - - Restructured the IDaemonResponse interface to provide information to CommandProcessor. + - Changed the "args" type on the `Imperative.parse` method to allow a string array. + - Restructured the IDaemonResponse interface to provide information to CommandProcessor. ## `5.0.0-next.202201061509` @@ -1029,10 +1043,10 @@ that would be used if a command were executed. ## `5.0.0-next.202112132158` - Enhancement: Added an environment variable to control whether or not sensitive data will be masked in the console output.
- This behavior excludes any TRACE level logs for both, Imperative.log and AppName.log.
- This behavior also excludes properties defined as secure by the plugin developers.
- If the schema definition is not found, we will exclude the following properties: user, password, tokenValue, and keyPassphrase.
- More information: [zowe/zowe-cli #1106](https://github.com/zowe/zowe-cli/issues/1106) + This behavior excludes any TRACE level logs for both, Imperative.log and AppName.log.
+ This behavior also excludes properties defined as secure by the plugin developers.
+ If the schema definition is not found, we will exclude the following properties: user, password, tokenValue, and keyPassphrase.
+ More information: [zowe/zowe-cli #1106](https://github.com/zowe/zowe-cli/issues/1106) ## `5.0.0-next.202112101814` @@ -1048,7 +1062,7 @@ that would be used if a command were executed. - Enhancement: Changed CLI prompt input to be hidden for properties designated as secure in team config. [zowe/zowe-cli#1106](https://github.com/zowe/zowe-cli/issues/1106) - BugFix: Improved error message when Keytar module fails to load. [#27](https://github.com/zowe/imperative/issues/27) - **Next Breaking** - - Removed the `ConfigProfiles.load` API method. Use the methods `ConfigLayers.find` and `ConfigSecure.securePropsForProfile` instead. [#568](https://github.com/zowe/imperative/issues/568) + - Removed the `ConfigProfiles.load` API method. Use the methods `ConfigLayers.find` and `ConfigSecure.securePropsForProfile` instead. [#568](https://github.com/zowe/imperative/issues/568) ## `5.0.0-next.202111301806` @@ -1062,7 +1076,7 @@ that would be used if a command were executed. - BugFix: Changed credentials to be stored securely by default for v1 profiles to be consistent with the experience for v2 profiles. [zowe/zowe-cli#1128](https://github.com/zowe/zowe-cli/issues/1128) - **Next Breaking** - - Removed the `credentialServiceName` property from ImperativeConfig. The default credential manager uses the `name` property instead. + - Removed the `credentialServiceName` property from ImperativeConfig. The default credential manager uses the `name` property instead. ## `5.0.0-next.202111101806` @@ -1073,12 +1087,12 @@ that would be used if a command were executed. - Enhancement: Added `autoStore` property to config JSON files which defaults to true. When this property is enabled and the CLI prompts you to enter connection info, the values you enter will be saved to disk (or credential vault if they are secure) for future use. [zowe/zowe-cli#923](https://github.com/zowe/zowe-cli/issues/923) - **Next Breaking** - - Changed the default behavior of `Config.set` so that it no longer coerces string values to other types unless the `parseString` option is true. + - Changed the default behavior of `Config.set` so that it no longer coerces string values to other types unless the `parseString` option is true. ## `5.0.0-next.202110201735` - **LTS Breaking** - - Changed the return value of the public `PluginManagementFacility.requirePluginModuleCallback` function + - Changed the return value of the public `PluginManagementFacility.requirePluginModuleCallback` function - BugFix: Updated the profiles list as soon as the plugin is installed. ## `5.0.0-next.202110191937` @@ -1090,7 +1104,7 @@ that would be used if a command were executed. - Enhancement: Added `config update-schemas [--depth ]` command. [zowe/zowe-cli#1059](https://github.com/zowe/zowe-cli/issues/1059) - Enhancement: Added the ability to update the global schema file when installing a new plugin. [zowe/zowe-cli#1059](https://github.com/zowe/zowe-cli/issues/1059) - **Next Breaking** - - Renamed public static function ConfigSchemas.loadProfileSchemas to ConfigSchemas.loadSchema + - Renamed public static function ConfigSchemas.loadProfileSchemas to ConfigSchemas.loadSchema ## `5.0.0-next.202110011948` @@ -1129,13 +1143,13 @@ that would be used if a command were executed. - Enhancement: Better support for comments in JSON - Bugfix: Revert schema changes related to additionalProperties. Re-enable IntelliSense when editing zowe.config.json files - **Next Breaking** - - Changed the schema paths and updated schema version + - Changed the schema paths and updated schema version ## `5.0.0-next.202106221817` - **Next Breaking** - - Replaced --user with --user-config on all config command groups due to conflict with --user option during config auto-initialization - - Replaced --global with --global-config on all config command groups for consistency + - Replaced --user with --user-config on all config command groups due to conflict with --user option during config auto-initialization + - Replaced --global with --global-config on all config command groups for consistency ## `5.0.0-next.202106212048` @@ -1144,16 +1158,16 @@ that would be used if a command were executed. ## `5.0.0-next.202106041929` - **LTS Breaking**: Removed the following previously deprecated items: - - ICliLoadProfile.ICliILoadProfile -- use ICliLoadProfile.ICliLoadProfile - - IImperativeErrorParms.suppressReport -- has not been used since 10/17/2018 - - IImperativeConfig.pluginBaseCliVersion -- has not been used since version 1.0.1 - - AbstractRestClient.performRest -- use AbstractRestClient.request - - AbstractSession.HTTP_PROTOCOL -- use SessConstants.HTTP_PROTOCOL - - AbstractSession.HTTPS_PROTOCOL -- use SessConstants.HTTPS_PROTOCOL - - AbstractSession.TYPE_NONE -- use SessConstants.AUTH_TYPE_NONE - - AbstractSession.TYPE_BASIC -- use SessConstants.AUTH_TYPE_BASIC - - AbstractSession.TYPE_BEARER -- use SessConstants.AUTH_TYPE_BEARER - - AbstractSession.TYPE_TOKEN -- use SessConstants.AUTH_TYPE_TOKEN + - ICliLoadProfile.ICliILoadProfile -- use ICliLoadProfile.ICliLoadProfile + - IImperativeErrorParms.suppressReport -- has not been used since 10/17/2018 + - IImperativeConfig.pluginBaseCliVersion -- has not been used since version 1.0.1 + - AbstractRestClient.performRest -- use AbstractRestClient.request + - AbstractSession.HTTP_PROTOCOL -- use SessConstants.HTTP_PROTOCOL + - AbstractSession.HTTPS_PROTOCOL -- use SessConstants.HTTPS_PROTOCOL + - AbstractSession.TYPE_NONE -- use SessConstants.AUTH_TYPE_NONE + - AbstractSession.TYPE_BASIC -- use SessConstants.AUTH_TYPE_BASIC + - AbstractSession.TYPE_BEARER -- use SessConstants.AUTH_TYPE_BEARER + - AbstractSession.TYPE_TOKEN -- use SessConstants.AUTH_TYPE_TOKEN ## `5.0.0-next.202104262004` @@ -1167,14 +1181,14 @@ that would be used if a command were executed. ## `5.0.0-next.202104071400` - Enhancement: Add the ProfileInfo API to provide the following functionality: - - Read configuration from disk. - - Transparently read either a new team configuration or old style profiles. - - Resolve order of precedence for profile argument values. - - Provide information to enable callers to prompt for missing profile arguments. - - Retain the location in which a profile or argument was found. - - Automatically initialize CredentialManager, including an option to specify a custom keytar module. - - Provide a means to postpone the loading of secure arguments until specifically requested by the calling app to delay loading sensitive data until it is needed. - - Provide access to the lower-level Config API to fully manipulate the team configuration file. + - Read configuration from disk. + - Transparently read either a new team configuration or old style profiles. + - Resolve order of precedence for profile argument values. + - Provide information to enable callers to prompt for missing profile arguments. + - Retain the location in which a profile or argument was found. + - Automatically initialize CredentialManager, including an option to specify a custom keytar module. + - Provide a means to postpone the loading of secure arguments until specifically requested by the calling app to delay loading sensitive data until it is needed. + - Provide access to the lower-level Config API to fully manipulate the team configuration file. ## `5.0.0-next.202103111923` @@ -1199,7 +1213,7 @@ that would be used if a command were executed. ## `5.0.0-next.202010161240` -- Enhancement: Allow process exit code to be passed to daemon clients. +- Enhancement: Allow process exit code to be passed to daemon clients. ## `5.0.0-next.202009251501` @@ -1377,25 +1391,25 @@ that would be used if a command were executed. - Add the --dd flag to profile creation to allow the profile to be created without the default values specified for that profile. - Use a token for authentication if a token is present in the underlying REST session object. - Added a new ConnectionPropsForSessCfg.addPropsOrPrompt function that places credentials (including a possible token) into a session configuration object. - - Plugins must use this function to create their sessions to gain the features of automatic token-handling and prompting for missing connection options. - - Connection information is obtained from the command line, environment variables, a service profile, a base profile, or from an option's default value in a service profile's definition, in that order. - - If key connection information is not supplied to any cor Zowe command, the command will prompt for: - - host - - port - - user - - and password - - Any prompt will timeout after 30 seconds so that it will not hang an automated script. + - Plugins must use this function to create their sessions to gain the features of automatic token-handling and prompting for missing connection options. + - Connection information is obtained from the command line, environment variables, a service profile, a base profile, or from an option's default value in a service profile's definition, in that order. + - If key connection information is not supplied to any cor Zowe command, the command will prompt for: + - host + - port + - user + - and password + - Any prompt will timeout after 30 seconds so that it will not hang an automated script. - Add base profiles, a new type of profile which can store values shared between profiles of other types. - - The properties that are currently recognized in a base profile are: - - host - - port - - user - - password - - rejectUnauthorized - - tokenType - - tokenValue - - To use base profiles in an Imperative-based CLI, define a `baseProfile` schema on your Imperative configuration object. - - If the `baseProfile` schema is defined, base profile support will be added to any command that uses profiles. + - The properties that are currently recognized in a base profile are: + - host + - port + - user + - password + - rejectUnauthorized + - tokenType + - tokenValue + - To use base profiles in an Imperative-based CLI, define a `baseProfile` schema on your Imperative configuration object. + - If the `baseProfile` schema is defined, base profile support will be added to any command that uses profiles. - Due to new options (like tokenValue) help text will change. Plugin developers may have to update any mismatched snapshots in their automated tests. - Updated the version of TypeScript from 3.7.4 to 3.8.0. - Updated the version of TSLint from 5.x to 6.1.2. diff --git a/packages/imperative/src/config/__tests__/ConfigUtils.unit.test.ts b/packages/imperative/src/config/__tests__/ConfigUtils.unit.test.ts index f064825c66..d50fe4ecbf 100644 --- a/packages/imperative/src/config/__tests__/ConfigUtils.unit.test.ts +++ b/packages/imperative/src/config/__tests__/ConfigUtils.unit.test.ts @@ -366,4 +366,38 @@ describe("Config Utils", () => { expect(writeFileSyncMock).toHaveBeenCalled(); }); }); + + describe("hasTokenExpired", () => { + it("returns false if an error occurred during parsing", async () => { + const jsonParseSpy = jest.spyOn(JSON, "parse").mockImplementation(() => { + throw new Error("Unknown error while parsing JSON"); + }); + expect(ConfigUtils.hasTokenExpired("HEADER.PAYLOAD.SIGNATURE")).toBe(false); + expect(jsonParseSpy).toHaveBeenCalled(); + }); + + it("returns true if a JWT token is present and has expired", async () => { + const jsonParseSpy = jest.spyOn(JSON, "parse").mockReturnValue({ + exp: 1000000000, + }); + expect(ConfigUtils.hasTokenExpired("HEADER.PAYLOAD.SIGNATURE")).toBe(true); + expect(jsonParseSpy).toHaveBeenCalled(); + }); + + it("returns false if a JWT payload can be parsed, but doesn't contain the exp property", async () => { + const jsonParseSpy = jest.spyOn(JSON, "parse").mockReturnValue({ + iat: 1000000000, + }); + expect(ConfigUtils.hasTokenExpired("HEADER.PAYLOAD.SIGNATURE")).toBe(false); + expect(jsonParseSpy).toHaveBeenCalled(); + }); + + it("returns false if a JWT token is present and has not expired", async () => { + const jsonParseSpy = jest.spyOn(JSON, "parse").mockReturnValue({ + exp: 5000000000, + }); + expect(ConfigUtils.hasTokenExpired("HEADER.PAYLOAD.SIGNATURE")).toBe(false); + expect(jsonParseSpy).toHaveBeenCalled(); + }); + }); }); diff --git a/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts b/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts index 420972d432..2c7330d8a8 100644 --- a/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts +++ b/packages/imperative/src/config/__tests__/ProfileInfo.TeamConfig.unit.test.ts @@ -1852,4 +1852,118 @@ describe("TeamConfig ProfileInfo tests", () => { }); // end schema management tests }); + + describe("hasTokenExpiredForProfile", () => { + function getBlockMocks() { + const profileInfo = createNewProfInfo(teamProjDir); + const getAllProfiles = jest.spyOn(profileInfo, "getAllProfiles") + .mockReturnValue([ + { + profName: "zosmf", + profType: "zosmf", + isDefaultProfile: false, + profLoc: { + locType: ProfLocType.TEAM_CONFIG, + osLoc: ["/a/b/c/zowe.config.json"], + jsonLoc: "profiles.zosmf", + }, + }, + ]); + const mergeArgsForProfile = jest.spyOn(profileInfo, "mergeArgsForProfile"); + + return { + getAllProfiles, + mergeArgsForProfile, + profileInfo + }; + } + + it("returns false if the profile uses LTPA for token type", async () => { + const blockMocks = getBlockMocks(); + const jsonParseSpy = jest.spyOn(JSON, "parse"); + blockMocks.mergeArgsForProfile.mockReturnValue({ + knownArgs: [ + { + argName: "tokenValue", + argValue: "SOMELTPA2TOKENTHATCANNOTBEDECODED", + dataType: "string", + argLoc: { + locType: ProfLocType.TEAM_CONFIG, + osLoc: ["/a/b/c/zowe.config.json"], + jsonLoc: "profiles.zosmf.properties.tokenValue", + } + }, + { + argName: "tokenType", + argValue: "LtpaToken2", + dataType: "string", + argLoc: { + locType: ProfLocType.TEAM_CONFIG, + osLoc: ["/a/b/c/zowe.config.json"], + jsonLoc: "profiles.zosmf.properties.tokenType", + } + } + ], + missingArgs: [] + }); + expect(blockMocks.profileInfo.hasTokenExpiredForProfile("zosmf")).toBe(false); + expect(jsonParseSpy).not.toHaveBeenCalled(); + }); + + it("returns false if no tokenValue is present", async () => { + const blockMocks = getBlockMocks(); + const jsonParseSpy = jest.spyOn(JSON, "parse"); + blockMocks.mergeArgsForProfile.mockReturnValue({ + knownArgs: [ + { + argName: "tokenType", + argValue: "apimlAuthenticationToken", + dataType: "string", + argLoc: { + locType: ProfLocType.TEAM_CONFIG, + osLoc: ["/a/b/c/zowe.config.json"], + jsonLoc: "profiles.zosmf.properties.tokenType", + } + } + ], + missingArgs: [] + }); + expect(blockMocks.profileInfo.hasTokenExpiredForProfile("zosmf")).toBe(false); + expect(jsonParseSpy).not.toHaveBeenCalled(); + }); + + it("returns result of ConfigUtils.hasTokenExpired if token value is present", async () => { + const blockMocks = getBlockMocks(); + const jsonParseSpy = jest.spyOn(JSON, "parse"); + const hasTokenExpired = jest.spyOn(ConfigUtils, "hasTokenExpired").mockReturnValue(true); + blockMocks.mergeArgsForProfile.mockReturnValue({ + knownArgs: [ + { + argName: "tokenValue", + argValue: "A.JWT.TOKEN", + dataType: "string", + argLoc: { + locType: ProfLocType.TEAM_CONFIG, + osLoc: ["/a/b/c/zowe.config.json"], + jsonLoc: "profiles.zosmf.properties.tokenValue", + } + }, + { + argName: "tokenType", + argValue: "apimlAuthenticationToken", + dataType: "string", + argLoc: { + locType: ProfLocType.TEAM_CONFIG, + osLoc: ["/a/b/c/zowe.config.json"], + jsonLoc: "profiles.zosmf.properties.tokenType", + } + } + ], + missingArgs: [] + }); + expect(blockMocks.profileInfo.hasTokenExpiredForProfile("zosmf")).toBe(true); + expect(hasTokenExpired).toHaveBeenCalledWith("A.JWT.TOKEN"); + expect(jsonParseSpy).not.toHaveBeenCalled(); + }); + }); }); diff --git a/packages/imperative/src/config/src/ConfigUtils.ts b/packages/imperative/src/config/src/ConfigUtils.ts index 79b8640537..dc7d0a5853 100644 --- a/packages/imperative/src/config/src/ConfigUtils.ts +++ b/packages/imperative/src/config/src/ConfigUtils.ts @@ -295,4 +295,29 @@ export class ConfigUtils { } return false; } + + /** + * Checks if the given token has expired. Supports JSON web tokens only. + * + * @param {string} token - The JSON web token to check + * @returns {boolean} Whether the token has expired. Returns `false` if the token cannot be decoded or an expire time is not specified in the payload. + */ + public static hasTokenExpired(token: string): boolean { + // JWT format: [header].[payload].[signature] + const tokenParts = token.split("."); + try { + const payloadJson = JSON.parse(Buffer.from(tokenParts[1], "base64url").toString("utf8")); + if ("exp" in payloadJson) { + // The expire time is stored in seconds since UNIX epoch. + // The Date constructor expects a timestamp in milliseconds. + const msPerSec = 1000; + const expireDate = new Date(payloadJson.exp * msPerSec); + return expireDate < new Date(); + } + } catch (err) { + return false; + } + + return false; + } } diff --git a/packages/imperative/src/config/src/ProfileInfo.ts b/packages/imperative/src/config/src/ProfileInfo.ts index 3b6824e1e8..b5d812260c 100644 --- a/packages/imperative/src/config/src/ProfileInfo.ts +++ b/packages/imperative/src/config/src/ProfileInfo.ts @@ -179,6 +179,33 @@ export class ProfileInfo { this.mImpLogger = ConfigUtils.initImpUtils(this.mAppName); } + /** + * Checks if a JSON web token is used for authenticating the given profile name. If so, it will decode the token to determine whether it has expired. + * + * @param {string | IProfileLoaded} profile - The name of the profile or the profile object to check the JSON web token for + * @returns {boolean} Whether the token has expired for the given profile. Returns `false` if a token value is not set or the token type is LTPA2. + */ + public hasTokenExpiredForProfile(profile: string | IProfileLoaded): boolean { + const profName = typeof profile === "string" ? profile : profile.name; + const profAttrs = this.getAllProfiles().find((prof) => prof.profName === profName); + const knownProps = this.mergeArgsForProfile(profAttrs, { getSecureVals: true }).knownArgs; + const tokenValueProp = knownProps.find((arg) => arg.argName === "tokenValue" && arg.argValue != null); + + // Ignore if tokenValue is not a prop + if (tokenValueProp == null) { + return false; + } + + const tokenTypeProp = knownProps.find((arg) => arg.argName === "tokenType"); + // Cannot decode LTPA tokens without private key + if (tokenTypeProp?.argValue == "LtpaToken2") { + return false; + } + + const fullToken = tokenValueProp.argValue.toString(); + return ConfigUtils.hasTokenExpired(fullToken); + } + /** * Update a given property in the config file. * @param options Set of options needed to update a given property