recycleactor commited on
Commit
c047ed9
·
verified ·
1 Parent(s): f92fb8a

Upload main.rs

Browse files
Files changed (1) hide show
  1. src/main.rs +79 -212
src/main.rs CHANGED
@@ -987,7 +987,7 @@ async fn gw_light_call(
987
  } else {
988
  client
989
  .post(url)
990
- .header("Content-Type", "text/plain;charset=UTF-8")
991
  .body(params.to_string())
992
  };
993
 
@@ -1002,9 +1002,6 @@ async fn gw_light_call(
1002
  .header(ACCEPT, "*/*")
1003
  .header("Origin", "https://www.deezer.com")
1004
  .header("Referer", "https://www.deezer.com/")
1005
- .header("Sec-Fetch-Site", "same-origin")
1006
- .header("Sec-Fetch-Mode", "cors")
1007
- .header("Sec-Fetch-Dest", "empty")
1008
  .header("X-Requested-With", "XMLHttpRequest")
1009
  .header("Accept-Language", "en-US,en;q=0.9")
1010
  .header(
@@ -1033,9 +1030,9 @@ async fn gw_light_call(
1033
  }
1034
 
1035
  if method == "deezer.getUserData" {
1036
- match do_req(client, url, method, api_token, &params, true).await {
1037
  Ok(v) => Ok(v),
1038
- Err(e1) => match do_req(client, url, method, api_token, &params, false).await {
1039
  Ok(v) => Ok(v),
1040
  Err(e2) => Err(format!("getUserData:{e1}; fallback:{e2}")),
1041
  },
@@ -1066,7 +1063,6 @@ async fn login(Json(req): Json<LoginReq>) -> impl IntoResponse {
1066
  }
1067
  let jar = Arc::new(Jar::default());
1068
  let url_deezer = "https://www.deezer.com".parse::<Url>().unwrap();
1069
- let url_api = "https://api.deezer.com".parse::<Url>().unwrap();
1070
  jar.add_cookie_str("comeback=1; Domain=.deezer.com", &url_deezer);
1071
  let client = reqwest::Client::builder()
1072
  .cookie_provider(jar.clone())
@@ -1074,36 +1070,6 @@ async fn login(Json(req): Json<LoginReq>) -> impl IntoResponse {
1074
  .build()
1075
  .unwrap();
1076
 
1077
- let mut access_token_out: Option<String> = None;
1078
- if let Ok(access_token) = oauth_access_token(&client, &email, &pass).await {
1079
- access_token_out = Some(access_token.clone());
1080
- let _ = client
1081
- .get("https://api.deezer.com/platform/generic/track/80085")
1082
- .header("Authorization", format!("Bearer {}", access_token))
1083
- .header(ACCEPT, "*/*")
1084
- .header("Accept-Language", "en-US,en;q=0.9")
1085
- .header(
1086
- "User-Agent",
1087
- "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0",
1088
- )
1089
- .send()
1090
- .await;
1091
-
1092
- if !jar_has_cookie(&jar, &url_deezer, "sid=") && !jar_has_cookie(&jar, &url_api, "sid=") {
1093
- let _ = client
1094
- .get("https://api.deezer.com/platform/generic/track/3135556")
1095
- .header("Authorization", format!("Bearer {}", access_token))
1096
- .header(ACCEPT, "*/*")
1097
- .header("Accept-Language", "en-US,en;q=0.9")
1098
- .header(
1099
- "User-Agent",
1100
- "Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0",
1101
- )
1102
- .send()
1103
- .await;
1104
- }
1105
- }
1106
-
1107
  let ud = match gw_light_call(&client, "deezer.getUserData", "null", json!({})).await {
1108
  Ok(v) => v,
1109
  Err(e) => return json_error(StatusCode::BAD_GATEWAY, e),
@@ -1119,33 +1085,29 @@ async fn login(Json(req): Json<LoginReq>) -> impl IntoResponse {
1119
  .map(|n| n.to_string())
1120
  .unwrap_or_default();
1121
 
1122
- let arl_v = match gw_light_call(&client, "user.getArl", &token, json!({})).await {
1123
- Ok(v) => v,
1124
- Err(e1) => {
1125
- let cred = gw_light_call(
1126
- &client,
1127
- "user.checkCredentials",
1128
- &token,
1129
- json!({
1130
- "login": email,
1131
- "password": pass,
1132
- "checkFormLogin": token
1133
- }),
1134
- )
1135
- .await;
1136
- if let Err(e) = cred {
1137
- return json_error(StatusCode::UNAUTHORIZED, e);
1138
- }
1139
- match gw_light_call(&client, "user.getArl", &token, json!({})).await {
1140
- Ok(v) => v,
1141
- Err(e2) => return json_error(StatusCode::BAD_GATEWAY, format!("getArl:{e1}; retry:{e2}")),
1142
- }
1143
- }
1144
- };
1145
 
1146
- let arl = arl_v.as_str().unwrap_or("").to_string();
1147
- if arl.len() < 20 {
1148
- return json_error(StatusCode::BAD_GATEWAY, "no arl");
 
 
 
 
 
1149
  }
1150
 
1151
  (StatusCode::OK, Json(json!({ "arl": arl, "token": token, "uid": uid, "access_token": access_token_out }))).into_response()
@@ -1234,6 +1196,13 @@ async fn pair_status(State(state): State<AppState>, Query(q): Query<PairStatusQu
1234
  )
1235
  .into_response();
1236
  }
 
 
 
 
 
 
 
1237
 
1238
  (StatusCode::OK, Json(json!({ "status": "pending" }))).into_response()
1239
  }
@@ -1358,42 +1327,6 @@ async fn api_deezer_get(
1358
  Ok(v)
1359
  }
1360
 
1361
- async fn upstream_login(email: &str, password_md5: &str) -> Result<serde_json::Value, String> {
1362
- let Some(base) = upstream_dzmedia_base() else {
1363
- return Err("upstream:disabled".to_string());
1364
- };
1365
- let url = format!("{base}/login");
1366
- let client = reqwest::Client::builder()
1367
- .timeout(std::time::Duration::from_secs(20))
1368
- .build()
1369
- .map_err(|_| "upstream:client".to_string())?;
1370
- let r = client
1371
- .post(url)
1372
- .json(&json!({ "email": email, "password_md5": password_md5 }))
1373
- .send()
1374
- .await
1375
- .map_err(|_| "upstream:network".to_string())?;
1376
-
1377
- let status = r.status();
1378
- let text = r.text().await.map_err(|_| "upstream:read".to_string())?;
1379
- let v: serde_json::Value = serde_json::from_str(&text).map_err(|_| {
1380
- let snip: String = text.chars().take(200).collect();
1381
- format!("upstream:parse:{}:{}", status.as_u16(), snip)
1382
- })?;
1383
- if !status.is_success() {
1384
- let msg = v
1385
- .get("error")
1386
- .and_then(|x| x.as_str())
1387
- .map(|s| s.to_string())
1388
- .unwrap_or_else(|| {
1389
- let snip: String = text.chars().take(200).collect();
1390
- format!("upstream:{}:{}", status.as_u16(), snip)
1391
- });
1392
- return Err(msg);
1393
- }
1394
- Ok(v)
1395
- }
1396
-
1397
  async fn pair_complete(State(state): State<AppState>, Form(f): Form<PairCompleteForm>) -> impl IntoResponse {
1398
  let code = f.code.trim().to_string();
1399
  let email = f.email.trim().to_string();
@@ -1422,138 +1355,72 @@ async fn pair_complete(State(state): State<AppState>, Form(f): Form<PairComplete
1422
  let mut access_token: Option<String> = None;
1423
  let mut uid: Option<String> = None;
1424
  let mut arl_out: Option<String> = None;
1425
- let mut login_err: Option<String> = None;
1426
  let mut gw_token: Option<String> = None;
1427
- let mut gw_err: Option<String> = None;
1428
 
1429
- match oauth_access_token(&client, &email, &pass_md5).await {
1430
- Ok(t) => access_token = Some(t),
1431
  Err(e) => {
1432
- login_err = Some(e.clone());
1433
- match upstream_login(&email, &pass_md5).await {
1434
- Ok(v) => {
1435
- if let Some(t) = v.get("access_token").and_then(|x| x.as_str()) {
1436
- if !t.trim().is_empty() {
1437
- access_token = Some(t.trim().to_string());
1438
- }
1439
- }
1440
- if let Some(u) = v.get("uid").and_then(|x| x.as_str()) {
1441
- if !u.trim().is_empty() {
1442
- uid = Some(u.trim().to_string());
1443
- }
1444
- } else if let Some(u) = v.get("uid").and_then(|x| x.as_i64()) {
1445
- uid = Some(u.to_string());
1446
- }
1447
- if let Some(a) = v.get("arl").and_then(|x| x.as_str()) {
1448
- if a.trim().len() > 20 {
1449
- arl_out = Some(a.trim().to_string());
1450
- }
1451
- }
1452
- }
1453
- Err(e2) => {
1454
- login_err = Some(format!("{e}; upstream:{e2}"));
1455
- }
1456
  }
 
 
1457
  }
1458
- }
1459
-
1460
- if let Some(tok) = access_token.as_ref() {
1461
- let _ = client
1462
- .get("https://api.deezer.com/platform/generic/track/80085")
1463
- .header("Authorization", format!("Bearer {}", tok))
1464
- .send()
1465
- .await;
1466
 
1467
- if uid.is_none() {
1468
- match api_deezer_get(&client, "/user/me", tok, &[]).await {
1469
- Ok(me) => uid = me.get("id").and_then(|x| x.as_i64()).map(|n| n.to_string()),
1470
- Err(e) => {
1471
- let mut map = state.pair.write().await;
1472
- if let Some(s) = map.get_mut(&code) {
1473
- s.error = Some(e.clone());
1474
- }
1475
- return Html(format!("<h3>Ошибка Deezer API</h3><pre>{}</pre>", htmlesc(&e))).into_response();
1476
- }
1477
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1478
  }
 
 
1479
  }
1480
 
1481
- if arl_out.is_none() {
1482
- match gw_light_call(&client, "deezer.getUserData", "null", json!({})).await {
1483
- Ok(ud) => {
1484
- let token = ud["checkForm"].as_str().unwrap_or("").to_string();
1485
- let gw_uid = ud["USER"]["USER_ID"]
1486
- .as_i64()
1487
- .map(|n| n.to_string())
1488
- .unwrap_or_default();
1489
- if !gw_uid.is_empty() && uid.is_none() {
1490
- uid = Some(gw_uid);
1491
- }
1492
- if !token.is_empty() {
1493
- gw_token = Some(token.clone());
1494
- match gw_light_call(
1495
- &client,
1496
- "user.checkCredentials",
1497
- &token,
1498
- json!({
1499
- "login": email,
1500
- "password": pass_md5,
1501
- "checkFormLogin": token
1502
- }),
1503
- )
1504
- .await
1505
- {
1506
- Ok(_) => match gw_light_call(&client, "user.getArl", &token, json!({})).await {
1507
- Ok(v) => {
1508
- if let Some(s) = v.as_str() {
1509
- if s.len() > 20 {
1510
- arl_out = Some(s.to_string());
1511
- } else {
1512
- gw_err = Some("gw:no_arl".to_string());
1513
- }
1514
- } else {
1515
- gw_err = Some("gw:no_arl".to_string());
1516
- }
1517
- }
1518
- Err(e) => {
1519
- gw_err = Some(format!("gw:getArl:{e}"));
1520
- }
1521
- },
1522
- Err(e) => {
1523
- gw_err = Some(format!("gw:checkCredentials:{e}"));
1524
- }
1525
- }
1526
- } else {
1527
- gw_err = Some("gw:no_checkForm".to_string());
1528
- }
1529
- }
1530
- Err(e) => {
1531
- gw_err = Some(format!("gw:getUserData:{e}"));
1532
  }
1533
  }
1534
  }
1535
 
1536
- if access_token.is_none() && arl_out.as_deref().unwrap_or("").len() < 20 {
1537
- let msg = match (login_err, gw_err) {
1538
- (Some(a), Some(b)) => format!("{a}; {b}"),
1539
- (Some(a), None) => a,
1540
- (None, Some(b)) => b,
1541
- (None, None) => "login_failed".to_string(),
1542
- };
1543
- let mut map = state.pair.write().await;
1544
- if let Some(s) = map.get_mut(&code) {
1545
- s.error = Some(msg.clone());
1546
- }
1547
- return Html(format!("<h3>Ошибка входа</h3><pre>{}</pre>", htmlesc(&msg))).into_response();
1548
  }
1549
 
1550
  {
1551
  let mut map = state.pair.write().await;
1552
  if let Some(s) = map.get_mut(&code) {
1553
  s.access_token = access_token;
1554
- if gw_token.is_some() {
1555
- s.token = gw_token;
1556
- }
1557
  s.user_id = uid;
1558
  s.email = Some(email);
1559
  s.arl = arl_out;
 
987
  } else {
988
  client
989
  .post(url)
990
+ .header("Content-Type", "application/json")
991
  .body(params.to_string())
992
  };
993
 
 
1002
  .header(ACCEPT, "*/*")
1003
  .header("Origin", "https://www.deezer.com")
1004
  .header("Referer", "https://www.deezer.com/")
 
 
 
1005
  .header("X-Requested-With", "XMLHttpRequest")
1006
  .header("Accept-Language", "en-US,en;q=0.9")
1007
  .header(
 
1030
  }
1031
 
1032
  if method == "deezer.getUserData" {
1033
+ match do_req(client, url, method, api_token, &params, false).await {
1034
  Ok(v) => Ok(v),
1035
+ Err(e1) => match do_req(client, url, method, api_token, &params, true).await {
1036
  Ok(v) => Ok(v),
1037
  Err(e2) => Err(format!("getUserData:{e1}; fallback:{e2}")),
1038
  },
 
1063
  }
1064
  let jar = Arc::new(Jar::default());
1065
  let url_deezer = "https://www.deezer.com".parse::<Url>().unwrap();
 
1066
  jar.add_cookie_str("comeback=1; Domain=.deezer.com", &url_deezer);
1067
  let client = reqwest::Client::builder()
1068
  .cookie_provider(jar.clone())
 
1070
  .build()
1071
  .unwrap();
1072
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1073
  let ud = match gw_light_call(&client, "deezer.getUserData", "null", json!({})).await {
1074
  Ok(v) => v,
1075
  Err(e) => return json_error(StatusCode::BAD_GATEWAY, e),
 
1085
  .map(|n| n.to_string())
1086
  .unwrap_or_default();
1087
 
1088
+ if let Err(e) = gw_light_call(
1089
+ &client,
1090
+ "user.checkCredentials",
1091
+ &token,
1092
+ json!({
1093
+ "login": email,
1094
+ "password": pass,
1095
+ "checkFormLogin": token
1096
+ }),
1097
+ )
1098
+ .await
1099
+ {
1100
+ return json_error(StatusCode::UNAUTHORIZED, e);
1101
+ }
 
 
 
 
 
 
 
 
 
1102
 
1103
+ let mut arl: String = String::new();
1104
+ if let Ok(v) = gw_light_call(&client, "user.getArl", &token, json!({})).await {
1105
+ arl = v.as_str().unwrap_or("").to_string();
1106
+ }
1107
+
1108
+ let mut access_token_out: Option<String> = None;
1109
+ if let Ok(access_token) = oauth_access_token(&client, &email, &pass).await {
1110
+ access_token_out = Some(access_token);
1111
  }
1112
 
1113
  (StatusCode::OK, Json(json!({ "arl": arl, "token": token, "uid": uid, "access_token": access_token_out }))).into_response()
 
1196
  )
1197
  .into_response();
1198
  }
1199
+ if sess.token.as_deref().unwrap_or("").trim().len() > 0 {
1200
+ return (
1201
+ StatusCode::OK,
1202
+ Json(json!({ "status": "ok", "access_token": null, "token": sess.token, "user_id": sess.user_id, "email": sess.email, "arl": sess.arl })),
1203
+ )
1204
+ .into_response();
1205
+ }
1206
 
1207
  (StatusCode::OK, Json(json!({ "status": "pending" }))).into_response()
1208
  }
 
1327
  Ok(v)
1328
  }
1329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1330
  async fn pair_complete(State(state): State<AppState>, Form(f): Form<PairCompleteForm>) -> impl IntoResponse {
1331
  let code = f.code.trim().to_string();
1332
  let email = f.email.trim().to_string();
 
1355
  let mut access_token: Option<String> = None;
1356
  let mut uid: Option<String> = None;
1357
  let mut arl_out: Option<String> = None;
 
1358
  let mut gw_token: Option<String> = None;
 
1359
 
1360
+ let ud = match gw_light_call(&client, "deezer.getUserData", "null", json!({})).await {
1361
+ Ok(v) => v,
1362
  Err(e) => {
1363
+ let mut map = state.pair.write().await;
1364
+ if let Some(s) = map.get_mut(&code) {
1365
+ s.error = Some(format!("gw:getUserData:{e}"));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1366
  }
1367
+ return Html(format!("<h3>Ошибка входа</h3><pre>{}</pre>", htmlesc(&format!("gw:getUserData:{e}"))))
1368
+ .into_response();
1369
  }
1370
+ };
 
 
 
 
 
 
 
1371
 
1372
+ let token = ud["checkForm"].as_str().unwrap_or("").to_string();
1373
+ if token.is_empty() {
1374
+ let msg = "gw:no_checkForm";
1375
+ let mut map = state.pair.write().await;
1376
+ if let Some(s) = map.get_mut(&code) {
1377
+ s.error = Some(msg.to_string());
1378
+ }
1379
+ return Html(format!("<h3>Ошибка входа</h3><pre>{}</pre>", htmlesc(msg))).into_response();
1380
+ }
1381
+ gw_token = Some(token.clone());
1382
+ uid = ud["USER"]["USER_ID"]
1383
+ .as_i64()
1384
+ .map(|n| n.to_string())
1385
+ .filter(|s| !s.trim().is_empty());
1386
+
1387
+ if let Err(e) = gw_light_call(
1388
+ &client,
1389
+ "user.checkCredentials",
1390
+ &token,
1391
+ json!({
1392
+ "login": email,
1393
+ "password": pass_md5,
1394
+ "checkFormLogin": token
1395
+ }),
1396
+ )
1397
+ .await
1398
+ {
1399
+ let mut map = state.pair.write().await;
1400
+ if let Some(s) = map.get_mut(&code) {
1401
+ s.error = Some(format!("gw:checkCredentials:{e}"));
1402
  }
1403
+ return Html(format!("<h3>Ошибка входа</h3><pre>{}</pre>", htmlesc(&format!("gw:checkCredentials:{e}"))))
1404
+ .into_response();
1405
  }
1406
 
1407
+ if let Ok(v) = gw_light_call(&client, "user.getArl", &token, json!({})).await {
1408
+ if let Some(s) = v.as_str() {
1409
+ if s.len() > 20 {
1410
+ arl_out = Some(s.to_string());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1411
  }
1412
  }
1413
  }
1414
 
1415
+ if let Ok(t) = oauth_access_token(&client, &email, &pass_md5).await {
1416
+ access_token = Some(t);
 
 
 
 
 
 
 
 
 
 
1417
  }
1418
 
1419
  {
1420
  let mut map = state.pair.write().await;
1421
  if let Some(s) = map.get_mut(&code) {
1422
  s.access_token = access_token;
1423
+ s.token = gw_token;
 
 
1424
  s.user_id = uid;
1425
  s.email = Some(email);
1426
  s.arl = arl_out;