PSMindMeister.psm1
function Get-JotFormApiKey { [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$ApiKey, [Parameter()] [ValidateNotNullOrEmpty()] [string]$RegistryKeyPath = 'HKCU:\Software\PSJotForm' ) $ErrorActionPreference = 'Stop' function decrypt([string]$TextToDecrypt) { $secure = ConvertTo-SecureString $TextToDecrypt $hook = New-Object system.Management.Automation.PSCredential("test", $secure) $plain = $hook.GetNetworkCredential().Password return $plain } try { if ($PSBoundParameters.ContainsKey('ApiKey')) { $script:JotFormAPIKey = $ApiKey $script:JotFormAPIKey } elseif (Get-Variable -Name JotFormAPIKey -Scope Script -ErrorAction Ignore) { $script:JotFormAPIKey } elseif (-not (Test-Path -Path $RegistryKeyPath)) { throw "No JotForm configuration found in registry" } elseif (-not ($keyValues = Get-ItemProperty -Path $RegistryKeyPath)) { throw 'JotForm API not found in registry' } else { $script:JotFormAPIKey = decrypt $keyValues.APIKey $script:JotFormAPIKey } } catch { Write-Error $_.Exception.Message } } function Get-MindMeisterApiAuthInfo { [CmdletBinding()] param ( [Parameter()] [string]$PersonalAccessToken, [Parameter()] [string]$SharedKey, [Parameter()] [string]$SecretKey, [Parameter()] [string]$V1Token, [Parameter()] [ValidateNotNullOrEmpty()] [string]$RegistryKeyPath = 'HKCU:\Software\PSMindMeister' ) $ErrorActionPreference = 'Stop' function decrypt([string]$TextToDecrypt) { $secure = ConvertTo-SecureString $TextToDecrypt $hook = New-Object system.Management.Automation.PSCredential("test", $secure) $plain = $hook.GetNetworkCredential().Password return $plain } try { if (-not $script:mindMeisterApiInfo) { $script:mindMeisterApiInfo = [pscustomobject]@{} } $params = 'PersonalAccessToken', 'SharedKey', 'SecretKey', 'V1Token' foreach ($param in $params) { if ($PSBoundParameters.ContainsKey($param)) { Write-Verbose -Message "Found API val [$($param)] in passed parameter." $script:mindMeisterApiInfo | Add-Member -NotePropertyName $param -NotePropertyValue (Get-Variable -Name $param).Value -Force } elseif ($param -notin $script:mindMeisterApiInfo.PSObject.Properties.Name) { if ($value = Get-ItemProperty -Path $RegistryKeyPath -Name $params -ErrorAction Ignore) { Write-Verbose -Message "Found API val [$($param)] in registry." $script:mindMeisterApiInfo | Add-Member -NotePropertyName $param -NotePropertyValue (decrypt $value.$param) } else { throw "The [$($param)] MindMeister API value could not be found." } } else { Write-Verbose -Message "Found API val [$($param)] in existing script variable." } } $script:mindMeisterApiInfo } catch { Write-Error $_.Exception.Message } } function Save-MindMeisterApiAuthInfo { [CmdletBinding()] param ( [Parameter()] [string]$V2PersonalAccessToken, [Parameter()] [string]$SharedKey, [Parameter()] [string]$SecretKey, [Parameter()] [string]$V1Token, [Parameter()] [string]$RegistryKeyPath = "HKCU:\Software\PSMindMeister" ) begin { function encrypt([string]$TextToEncrypt) { $secure = ConvertTo-SecureString $TextToEncrypt -AsPlainText -Force $encrypted = $secure | ConvertFrom-SecureString return $encrypted } } process { if (-not (Test-Path -Path $RegistryKeyPath)) { New-Item -Path ($RegistryKeyPath | Split-Path -Parent) -Name ($RegistryKeyPath | Split-Path -Leaf) | Out-Null } $values = $PSBoundParameters.GetEnumerator().where({ $_.Key -ne 'RegistryKeyPath' -and $_.Value}) | Select-Object -ExpandProperty Key foreach ($val in $values) { Write-Verbose "Creating $RegistryKeyPath\$val" New-ItemProperty $RegistryKeyPath -Name $val -Value $(encrypt $((Get-Variable $val).Value)) -Force | Out-Null } } } function Get-MindMeisterApiV1Signature { [OutputType('void')] [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [hashtable]$Parameters ) $ErrorActionPreference = 'Stop' function Get-MD5Hash { param($String) $md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider $utf8 = new-object -TypeName System.Text.UTF8Encoding ([System.BitConverter]::ToString($md5.ComputeHash($utf8.GetBytes($String))) -replace '-').ToLower() } $secretKey = Get-MindMeisterApiAuthInfo | Select-Object -ExpandProperty SecretKey $paramsSorted = [ordered]@{} $Parameters.Keys | Sort-Object | ForEach-Object { $paramsSorted[$_] = $Parameters[$_] } $paramString = '' $paramsSorted.GetEnumerator().foreach({ $paramString += "$($_.Key)$($_.Value)" }) $paramString = "$($secretKey)$paramString" Get-MD5Hash -String $paramString } function Connect-MindMeisterApiV1 { [OutputType('void')] [CmdletBinding()] param () $ErrorActionPreference = 'Stop' $script:frob = (Invoke-MindMeisterApiCallV1 -ApiMethod 'mm.auth.getFrob').frob $parameters = @{ perms = 'delete' api_key = (Get-MindMeisterApiAuthInfo | Select-Object -ExpandProperty SharedKey) frob = $script:frob } $sig = Get-MindMeisterApiV1Signature -Parameters $parameters $paramString = ConvertTo-UriParameters -HttpBody $parameters $authUri = "http://www.mindmeister.com/services/auth/?$paramString&api_sig=$sig" Start-Process $authUri if ($token = (Invoke-MindMeisterApiCallV1 -ApiMethod 'mm.auth.getToken' -Parameters @{'frob' = $script:frob }).auth.token) { Save-MindMeisterApiAuthInfo -V1Token $token } else { throw 'Could not retrieve token.' } } function Invoke-MindMeisterApiCallV2 { [OutputType('pscustomobject')] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Endpoint, [Parameter()] [string]$HttpMethod = 'GET', [Parameter()] [ValidateNotNullOrEmpty()] [hashtable]$Payload ) begin { $ErrorActionPreference = 'Stop' $apiCreds = Get-MindMeisterApiAuthInfo } process { $invRestParams = @{ Method = $HttpMethod Uri = "https://www.mindmeister.com/api/v2/$Endpoint" Headers = @{ 'Authorization' = "Bearer $($apiCreds.V2PersonalAccessToken)" 'Content-Type' = 'application/json' } ErrorAction = 'Stop' } Invoke-RestMethod @invRestParams } } function ConvertTo-UriParameters { [OutputType('string')] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [hashtable]$HttpBody ) $ErrorActionPreference = 'Stop' $params = @() $HttpBody.GetEnumerator().foreach({ $params += "$($_.Key)=$($_.Value)" }) $params -join '&' } function Invoke-MindMeisterApiCallV1 { [OutputType('pscustomobject')] [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$ApiMethod, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateSet('auth', 'rest')] [string]$ApiService = 'rest', [Parameter()] [string]$HttpMethod = 'GET', [Parameter()] [ValidateNotNullOrEmpty()] [hashtable]$Parameters ) $ErrorActionPreference = 'Stop' $paramsToSign = @{ 'api_key' = (Get-MindMeisterApiAuthInfo).SharedKey 'response_format' = 'xml' } if ($PSBoundParameters.ContainsKey('Parameters')) { $Parameters.GetEnumerator() | ForEach-Object { $paramsToSign[$_.Key] = $_.Value } } if ($PSBoundParameters.ContainsKey('ApiMethod')) { $paramsToSign.method = $ApiMethod if ($ApiMethod -notlike 'mm.auth*') { $paramsToSign.auth_token = (Get-MindMeisterApiAuthInfo).V1Token } } $sig = Get-MindMeisterApiV1Signature -Parameters $paramsToSign $paramString = ConvertTo-UriParameters -HttpBody ($paramsToSign + @{'api_sig' = $sig}) $uri = 'https://www.mindmeister.com/services/{0}?{1}' -f $ApiService, $paramString $invRestParams = @{ Uri = $uri Method = $HttpMethod ErrorAction = 'Stop' } $result = Invoke-RestMethod @invRestParams if ($result.stat -eq 'fail') { throw $result.rsp.err.msg } else { $result.rsp } } function Get-MindMeisterMap { [OutputType('pscustomobject')] [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [int]$Id, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Name ) $ErrorActionPreference = 'Stop' if ($PSBoundParameters.Keys.Count -eq 0) { (Invoke-MindMeisterApiCallV1 -ApiMethod 'mm.maps.getList').maps.map } elseif ($PSBoundParameters.ContainsKey('Name')) { $result = (Invoke-MindMeisterApiCallV1 -ApiMethod 'mm.maps.getList').maps.map if ($map = $result.where({ $_.title -eq $Name })) { Get-MindMeisterMap -Id $map.id } } elseif ($PSBoundParameters.ContainsKey('Id')) { Invoke-MindMeisterApiCallV1 -ApiMethod 'mm.maps.getMap' -Parameters @{ 'map_id' = $Id } } } |