{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$defs": {
    "LoginSessionRequest": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "client_id",
        "client_secret",
        "session_key",
        "provider",
        "redirect_uri"
      ],
      "properties": {
        "client_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100
        },
        "client_secret": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "session_key": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{43}$"
        },
        "provider": {
          "$ref": "#/$defs/Provider"
        },
        "redirect_uri": {
          "$ref": "#/$defs/RedirectUri"
        }
      }
    },
    "LoginSessionResponse": {
      "type": "object",
      "required": [
        "authorization_url",
        "expires_in"
      ],
      "properties": {
        "authorization_url": {
          "$ref": "#/$defs/RedirectUri"
        },
        "expires_in": {
          "type": "integer",
          "const": 600
        }
      }
    },
    "LoginResultRequest": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "client_id",
        "client_secret",
        "session_key",
        "redirect_uri"
      ],
      "properties": {
        "client_id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 100
        },
        "client_secret": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "session_key": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{43}$"
        },
        "redirect_uri": {
          "$ref": "#/$defs/RedirectUri"
        }
      }
    },
    "LoginResult": {
      "type": "object",
      "required": [
        "status"
      ],
      "properties": {
        "status": {
          "type": "string",
          "enum": [
            "pending",
            "succeeded",
            "failed"
          ]
        },
        "profile": {
          "$ref": "#/$defs/Profile"
        },
        "error": {
          "type": "string",
          "enum": [
            "access_denied",
            "invalid_provider_response",
            "provider_unavailable"
          ]
        }
      }
    },
    "Provider": {
      "type": "string",
      "enum": [
        "google",
        "github"
      ]
    },
    "RedirectUri": {
      "type": "string",
      "format": "uri",
      "maxLength": 2048,
      "x-validation": "redirect",
      "description": "Exact registered HTTPS URL or HTTP loopback; no credentials, query or fragment."
    },
    "TokenRequest": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "grant_type",
        "client_id",
        "client_secret",
        "code",
        "redirect_uri",
        "code_verifier"
      ],
      "properties": {
        "grant_type": {
          "type": "string",
          "const": "authorization_code"
        },
        "client_id": {
          "type": "string",
          "maxLength": 100
        },
        "client_secret": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "code": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "redirect_uri": {
          "$ref": "#/$defs/RedirectUri"
        },
        "code_verifier": {
          "type": "string",
          "pattern": "^[A-Za-z0-9._~-]{43,128}$"
        }
      }
    },
    "TokenResponse": {
      "type": "object",
      "required": [
        "access_token",
        "token_type",
        "expires_in",
        "scope"
      ],
      "properties": {
        "access_token": {
          "type": "string",
          "pattern": "^aop_[A-Za-z0-9_-]{43}$"
        },
        "token_type": {
          "type": "string",
          "const": "Bearer"
        },
        "expires_in": {
          "type": "integer",
          "const": 900
        },
        "scope": {
          "type": "string",
          "const": "profile"
        }
      }
    },
    "Profile": {
      "type": "object",
      "required": [
        "subject",
        "provider",
        "providerSubject",
        "name",
        "username",
        "email",
        "emailVerified",
        "avatarUrl"
      ],
      "properties": {
        "subject": {
          "type": "string"
        },
        "provider": {
          "$ref": "#/$defs/Provider"
        },
        "providerSubject": {
          "type": "string"
        },
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "username": {
          "type": [
            "string",
            "null"
          ]
        },
        "email": {
          "type": [
            "string",
            "null"
          ]
        },
        "emailVerified": {
          "type": "boolean"
        },
        "avatarUrl": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "ProviderStatus": {
      "type": "object",
      "required": [
        "id",
        "configured",
        "enabled",
        "available"
      ],
      "properties": {
        "id": {
          "$ref": "#/$defs/Provider"
        },
        "configured": {
          "type": "boolean"
        },
        "enabled": {
          "type": "boolean"
        },
        "available": {
          "type": "boolean"
        }
      }
    },
    "ProviderStatuses": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/ProviderStatus"
      }
    },
    "ApiError": {
      "type": "object",
      "required": [
        "error"
      ],
      "properties": {
        "error": {
          "type": "string"
        },
        "message": {
          "type": "string"
        }
      }
    },
    "Transaction": {
      "type": "object",
      "required": [
        "state",
        "codeVerifier",
        "codeChallenge",
        "createdAt",
        "expiresAt"
      ],
      "properties": {
        "state": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{43}$"
        },
        "codeVerifier": {
          "type": "string",
          "pattern": "^[A-Za-z0-9._~-]{43,128}$"
        },
        "codeChallenge": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{43}$"
        },
        "createdAt": {
          "type": "integer"
        },
        "expiresAt": {
          "type": "integer"
        }
      }
    }
  }
}
