Types/OpenPackage.Publisher/com.atproto.server.createSession.ps1

<#
.SYNOPSIS
    Creates an at protocol server session
.DESCRIPTION
    Creates an at protocol server session.
.NOTES
    This can be used by other publishers in order to connect to at protocol.
.LINK
    https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/server/createSession.json
#>

[CmdletBinding(PositionalBinding=$false,SupportsShouldProcess)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
    "PSAvoidUsingPlainTextForPassword", 
    "", 
    Justification="
    SecureStrings are not actually more secure.
    Use -Credential to avoid potential information disclosure in Windows event logs.
    "

)]
param(
# Handle or other identifier supported by the server for the authenticating user.
[Parameter(Mandatory,ParameterSetName='IdentifierAndPassword')]
[string]
$Identifier,

# The app password or account password.
[Parameter(Mandatory,ParameterSetName='IdentifierAndAppPassword')]
[string]
$AppPassword,

# A credential used to connect.
# The username will be treated as the `-Identifier`.
# The password will be treated as the `-AppPassword`
[Parameter(Mandatory,ParameterSetName='Credential')]
[Management.Automation.PSCredential]
[Alias('PSCredential')]
$Credential,

# The personal data server used for the connection.
[Alias('PersonalDataServer')]
[string]
$PDS = "https://bsky.social/"
)

# Declare the namespace ID
$NamespaceID = 'com.atproto.server.createSession'
# and the HTTP method used to connect
$httpMethod  = 'POST'

# Create a full url using the PDS and NamespaceId
$authenicationUrl = "$(
    # If the pds started with https://
    if ($pds -like 'https://*') {
        # just trim trailing slashes from https urls.
        $pds -replace '/$'
    } else {
        # Prefix anything else by https://
        "https://$pds" -replace '/$'
})/xrpc/$NamespaceID"


# Prepare our parameters to Invoke-RestMethod
$atSplat = [Ordered]@{
    Uri = $authenicationUrl
    Method = $httpMethod
    ContentType='application/json'
    Body = [Ordered]@{}
}

# Set our identifier and password
$atSplat.body.identifier, $atSplat.body.password = 
    if ($Identifier -and $AppPassword) {
        $Identifier, $AppPassword
    }
    elseif ($Credential) {
        $Credential.UserName
        $Credential.GetNetworkCredential().Password
    } else {
        Write-Warning "Missing authentication details. Provide a -Credential or -Identity and -AppPassword."
        return
    }

# and convert our body into json.
$atSplat.body = $atSplat.body | ConvertTo-Json -Depth 4    

# If `-WhatIf` was passed
if ($WhatIfPreference) {
    # remove sensitive information
    $atSplat.Remove('Body')
    return $atSplat # and return the splat.
}

# Otherwise, connect.
$authenticated = Invoke-RestMethod @atSplat

# If the connection does not have an accessJwt, return
if (-not $authenticated.accessJwt) { return }

# Force `atproto.session` objects to only display the handle and did by default
$updateTypeDataSplat = [Ordered]@{
    Force=$true
    TypeName='atproto.session'
    DefaultDisplayPropertySet  = 'handle','did'
}

# This prevents sensitive information from being displayed by default
# (like the email or the accessJwt)
Update-TypeData @updateTypeDataSplat

# Decorate our return data
$authenticated.pstypenames.add('atproto.session')
# and return our authenticated object.
return $authenticated