siwa-async 0.5.0

Sign In With Apple Validation in Async Rust
Documentation
use std::collections::HashMap;

use hyper::{body, Body, Client, Request};
use hyper_tls::HttpsConnector;
use serde::{Deserialize, Serialize};

use super::{error::Error, error::Result};

use super::constants::APPLE_PUB_KEYS_ENDPOINT;

/// Apple's public JSON Web Key
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub(crate) struct ApplePublicJWK {
	/// encryption algorithm
	pub alg: String,
	/// exponent value for RSA public
	pub e: String,
	/// 10-character identifier key from registered developer account
	pub kid: String,
	/// key type parameter setting: "RSA" only.
	pub kty: String,
	/// modulus value
	pub n: String,
	/// Intention
	pub r#use: String,
}

pub(crate) async fn fetch_apple_keys(
) -> Result<HashMap<String, ApplePublicJWK>> {
	let https = HttpsConnector::new();
	let client = Client::builder().build::<_, hyper::Body>(https);

	let req = Request::builder()
		.method("GET")
		.uri(APPLE_PUB_KEYS_ENDPOINT)
		.body(Body::from(""))?;

	let resp = client.request(req).await?;
	let buf = body::to_bytes(resp).await?;

	let mut resp: HashMap<String, Vec<ApplePublicJWK>> =
		serde_json::from_slice(&buf)?;

	resp.remove("keys").map_or(Err(Error::AppleKeys), |res| {
		Ok(res
			.into_iter()
			.map(|val| (val.kid.clone(), val))
			.collect::<HashMap<String, ApplePublicJWK>>())
	})
}