Tests/Test-RefreshToken.ps1

# Quick Refresh Token Test Script
# Tests Issue #208 fix - verifies refresh tokens are properly stored and can be used for subsequent refreshes

# Import module
Import-Module "$PSScriptRoot\..\IntuneWin32App.psd1" -Force

# Configuration
$TenantID = "cec1aa3f-dff2-48dd-8ddb-7c83e39f4547"
$ClientID = "d11ae3e7-b1aa-4b05-b769-4c6113b5263b"

Write-Host "`n=== Refresh Token Test (Issue #208) ===" -ForegroundColor Cyan
Write-Host "This test verifies that refresh tokens are properly stored and reused`n" -ForegroundColor Gray

# Step 1: Initial Authentication
Write-Host "Step 1: Initial Authentication" -ForegroundColor Yellow
$AuthResult = Connect-MSIntuneGraph -TenantID $TenantID -ClientID $ClientID -Interactive

if (-not $AuthResult) {
    Write-Host "Authentication failed" -ForegroundColor Red
    exit 1
}

Write-Host " [PASS] Authentication successful" -ForegroundColor Green

# Check initial token state
$InitialAccessToken = $Global:AccessToken.AccessToken
$InitialRefreshToken = if ($Global:AccessToken.PSObject.Properties["RefreshToken"]) { $Global:AccessToken.RefreshToken } else { $null }
$InitialScopes = if ($Global:AccessToken.PSObject.Properties["Scopes"]) { $Global:AccessToken.Scopes } else { @() }

Write-Host " Initial Access Token (last 30 chars): ...$($InitialAccessToken.Substring($InitialAccessToken.Length - 30))" -ForegroundColor Gray
if ($InitialRefreshToken) {
    Write-Host " Initial Refresh Token (last 30 chars): ...$($InitialRefreshToken.Substring($InitialRefreshToken.Length - 30))" -ForegroundColor Gray
    Write-Host " [PASS] Refresh token present" -ForegroundColor Green
}
else {
    Write-Host " [FAIL] No refresh token found" -ForegroundColor Red
    exit 1
}
Write-Host " Scopes: $($InitialScopes -join ', ')" -ForegroundColor Gray

# Step 2: First Refresh
Write-Host "`nStep 2: First Token Refresh (even though token is still valid)" -ForegroundColor Yellow
Start-Sleep -Seconds 2

$FirstRefreshResult = Connect-MSIntuneGraph -TenantID $TenantID -ClientID $ClientID -Refresh

if (-not $FirstRefreshResult) {
    Write-Host " [FAIL] First refresh failed" -ForegroundColor Red
    exit 1
}

$FirstRefreshedAccessToken = $Global:AccessToken.AccessToken
$FirstRefreshedRefreshToken = if ($Global:AccessToken.PSObject.Properties["RefreshToken"]) { $Global:AccessToken.RefreshToken } else { $null }

# Verify new access token
if ($FirstRefreshedAccessToken -ne $InitialAccessToken) {
    Write-Host " [PASS] New access token issued (tokens are different)" -ForegroundColor Green
    Write-Host " New Access Token (last 30 chars): ...$($FirstRefreshedAccessToken.Substring($FirstRefreshedAccessToken.Length - 30))" -ForegroundColor Gray
}
else {
    Write-Host " [FAIL] Same access token returned (tokens are identical)" -ForegroundColor Red
    Write-Host " Token: ...$($FirstRefreshedAccessToken.Substring($FirstRefreshedAccessToken.Length - 30))" -ForegroundColor Gray
}

# Verify refresh token is present (Issue #208 fix)
if ($FirstRefreshedRefreshToken) {
    if ($FirstRefreshedRefreshToken -ne $InitialRefreshToken) {
        Write-Host " [PASS] New refresh token issued (Issue #208 FIX)" -ForegroundColor Green
        Write-Host " New Refresh Token (last 30 chars): ...$($FirstRefreshedRefreshToken.Substring($FirstRefreshedRefreshToken.Length - 30))" -ForegroundColor Gray
    }
    else {
        Write-Host " [INFO] Same refresh token returned (this is OK, Azure AD may reuse refresh tokens)" -ForegroundColor Yellow
        Write-Host " Refresh Token (last 30 chars): ...$($FirstRefreshedRefreshToken.Substring($FirstRefreshedRefreshToken.Length - 30))" -ForegroundColor Gray
    }
    Write-Host " [PASS] Refresh token stored and available for next refresh (Issue #208 FIX)" -ForegroundColor Green
}
else {
    Write-Host " [FAIL] Refresh token missing after first refresh (Issue #208 BUG)" -ForegroundColor Red
    Write-Host " This means subsequent refreshes will fail!" -ForegroundColor Red
    exit 1
}

# Step 3: Second Refresh (proves token continuity)
Write-Host "`nStep 3: Second Token Refresh (proves refresh token chain works)" -ForegroundColor Yellow
Start-Sleep -Seconds 2

$SecondRefreshResult = Connect-MSIntuneGraph -TenantID $TenantID -ClientID $ClientID -Refresh

if (-not $SecondRefreshResult) {
    Write-Host " [FAIL] Second refresh failed" -ForegroundColor Red
    exit 1
}

$SecondRefreshedAccessToken = $Global:AccessToken.AccessToken
$SecondRefreshedRefreshToken = if ($Global:AccessToken.PSObject.Properties["RefreshToken"]) { $Global:AccessToken.RefreshToken } else { $null }

# Verify another new access token
if ($SecondRefreshedAccessToken -ne $FirstRefreshedAccessToken) {
    Write-Host " [PASS] New access token issued on second refresh (tokens are different)" -ForegroundColor Green
    Write-Host " New Access Token (last 30 chars): ... $($SecondRefreshedAccessToken.Substring($SecondRefreshedAccessToken.Length - 30))" -ForegroundColor Gray
}
else {
    Write-Host " [FAIL] Same access token returned (tokens are identical)" -ForegroundColor Red
    Write-Host " Token: ...$($SecondRefreshedAccessToken.Substring($SecondRefreshedAccessToken.Length - 30))" -ForegroundColor Gray
}

# Verify refresh token chain is maintained (critical for Issue #208)
if ($SecondRefreshedRefreshToken) {
    Write-Host " [PASS] Refresh token chain maintained (Issue #208 VERIFIED)" -ForegroundColor Green
    if ($SecondRefreshedRefreshToken -ne $FirstRefreshedRefreshToken) {
        Write-Host " Final Refresh Token (last 30 chars): ... $($SecondRefreshedRefreshToken.Substring($SecondRefreshedRefreshToken.Length - 30))" -ForegroundColor Gray
    }
    else {
        Write-Host " Refresh Token (last 30 chars): ... $($SecondRefreshedRefreshToken.Substring($SecondRefreshedRefreshToken.Length - 30))" -ForegroundColor Gray
        Write-Host " (Note: Azure AD reused same refresh token, this is normal)" -ForegroundColor Gray
    }
}
else {
    Write-Host " [FAIL] Refresh token chain broken" -ForegroundColor Red
    exit 1
}

# Verify refresh token chain is maintained (critical for Issue #208)
if ($SecondRefreshedRefreshToken) {
    Write-Host " [PASS] Refresh token chain maintained (Issue #208 VERIFIED)" -ForegroundColor Green
    Write-Host " Final Refresh Token: $($SecondRefreshedRefreshToken.Substring(0, 20))" -ForegroundColor Gray
}
else {
    Write-Host " [FAIL] Refresh token chain broken" -ForegroundColor Red
    exit 1
}

# Final Summary
Write-Host "`n=== Test Summary ===" -ForegroundColor Cyan
Write-Host " Initial authentication: SUCCESS" -ForegroundColor Green
Write-Host " First refresh: SUCCESS" -ForegroundColor Green
Write-Host " Refresh token stored after first refresh: SUCCESS" -ForegroundColor Green
Write-Host " Second refresh: SUCCESS" -ForegroundColor Green
Write-Host " Refresh token chain maintained: SUCCESS" -ForegroundColor Green
Write-Host "`n Issue #208 Fix: VERIFIED" -ForegroundColor Green -BackgroundColor Black
Write-Host " Refresh tokens are properly stored and reused for subsequent refreshes`n" -ForegroundColor Green