Private/Test-TokenValidity.ps1
Function Test-TokenValidity { <# .SYNOPSIS Checks if the provided JWT token is still valid or has expired .DESCRIPTION Decodes the JWT token and checks the expiration time against current time .PARAMETER authToken The SecureString containing the JWT token to validate .OUTPUTS Boolean - True if token is valid, False if expired or invalid #> [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory = $true)] [System.Security.SecureString] $authToken ) try { # Convert SecureString to plain text $ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($authToken) try { $plainToken = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr) # Extract payload from JWT (second part) $parts = $plainToken -split '\.' if ($parts.Count -lt 2) { Write-Log "Invalid token format" return $false } # Decode base64 (with padding fix) $payload = $parts[1] $padding = 4 - ($payload.Length % 4) if ($padding -lt 4) { $payload = $payload + ("=" * $padding) } $decodedBytes = [System.Convert]::FromBase64String($payload.Replace('-', '+').Replace('_', '/')) $jsonPayload = [System.Text.Encoding]::UTF8.GetString($decodedBytes) # Convert to object and check exp field $tokenData = $jsonPayload | ConvertFrom-Json if (-not $tokenData.exp) { Write-Log "Token missing expiration time" return $false } # Convert Unix timestamp to DateTime $expiration = [DateTime]::UnixEpoch.AddSeconds($tokenData.exp) $currentTime = [DateTime]::UtcNow # Add buffer time (30 seconds) to avoid edge cases $isValid = $expiration -gt $currentTime.AddSeconds(30) if (-not $isValid) { Write-Log "Token expired at $expiration (current time: $currentTime)" } return $isValid } finally { # Clean up the unmanaged string [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr) } } catch { Write-Log "Error validating token: $($_.Exception.Message)" # On any error, return false to trigger token refresh return $false } } |