Skip to main content

roblox_api/api/auth_token_service/
v1.rs

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::{DateTime, Error, client::Client};
5
6pub const URL: &str = "https://apis.roblox.com/auth-token-service/v1";
7
8// TODO: look into `metadata`
9
10#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
11pub enum LoginStatus {
12    Created,
13    Validated,
14}
15
16#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
17#[serde(rename_all = "camelCase")]
18pub struct LoginToken {
19    pub code: String,
20    pub status: String,
21    pub private_key: String,
22    pub expiration_time: DateTime,
23    pub image_path: String,
24}
25
26#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
27#[serde(rename_all = "camelCase")]
28pub struct LoginTokenStatus {
29    pub status: LoginStatus,
30    pub account_name: Option<String>,
31    pub account_picture_url: Option<String>,
32    pub expiration_time: String,
33}
34
35#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
36#[serde(rename_all = "camelCase")]
37pub struct InspectionInfo {
38    pub location: String,
39    pub device_info: String,
40}
41
42pub async fn login_create(client: &mut Client) -> Result<LoginToken, Error> {
43    client
44        .requestor
45        .request::<()>(
46            Method::POST,
47            &format!("{URL}/login/create"),
48            None,
49            None,
50            None,
51        )
52        .await?
53        .json::<LoginToken>()
54        .await
55}
56
57pub async fn login_cancel(client: &mut Client, code: &str) -> Result<(), Error> {
58    #[derive(Serialize)]
59    struct Request<'a> {
60        code: &'a str,
61    }
62
63    client
64        .requestor
65        .request::<Request>(
66            Method::POST,
67            &format!("{URL}/login/cancel"),
68            Some(&Request { code }),
69            None,
70            None,
71        )
72        .await?;
73
74    Ok(())
75}
76
77pub async fn login_status(
78    client: &mut Client,
79    code: &str,
80    key: &str,
81) -> Result<LoginTokenStatus, Error> {
82    #[derive(Serialize)]
83    struct Request<'a> {
84        code: &'a str,
85        #[serde(rename = "privateKey")]
86        key: &'a str,
87    }
88
89    client
90        .requestor
91        .request::<Request>(
92            Method::POST,
93            &format!("{URL}/login/status"),
94            Some(&Request { code, key }),
95            None,
96            None,
97        )
98        .await?
99        .json::<LoginTokenStatus>()
100        .await
101}
102
103pub async fn inspect_code(client: &mut Client, code: &str) -> Result<InspectionInfo, Error> {
104    #[derive(Serialize)]
105    struct Request<'a> {
106        code: &'a str,
107    }
108
109    client
110        .requestor
111        .request::<Request>(
112            Method::POST,
113            &format!("{URL}/login/enterCode"),
114            Some(&Request { code }),
115            None,
116            None,
117        )
118        .await?
119        .json::<InspectionInfo>()
120        .await
121}
122
123pub async fn validate_code(client: &mut Client, code: &str) -> Result<(), Error> {
124    #[derive(Serialize)]
125    struct Request<'a> {
126        code: &'a str,
127    }
128
129    client
130        .requestor
131        .request::<Request>(
132            Method::POST,
133            &format!("{URL}/login/validateCode"),
134            Some(&Request { code }),
135            None,
136            None,
137        )
138        .await?;
139
140    Ok(())
141}
142
143pub async fn qr_code_image(client: &mut Client, key: &str, code: &str) -> Result<Vec<u8>, Error> {
144    client
145        .requestor
146        .request::<()>(
147            Method::GET,
148            &format!("{URL}/login/qr-code-image"),
149            None,
150            Some(&[("key", key), ("code", code)]),
151            None,
152        )
153        .await?
154        .bytes()
155        .await
156}