odaislib 1.0.8__tar.gz → 1.0.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: odaislib
3
- Version: 1.0.8
3
+ Version: 1.0.9
4
4
  Summary: Facebook Authentication Library with multiple login methods
5
5
  Home-page:
6
6
  Author: Odai
@@ -318,319 +318,48 @@ class mobile:
318
318
  }
319
319
  class apps:
320
320
  @staticmethod
321
- def get_linked_apps(cookies):
322
- headers = {
323
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0",
324
- "Host": "m.facebook.com",
325
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
326
- }
327
- cookie_str = f"datr={cookies.get('datr', '')}; fr={cookies.get('fr', '')}; sb=3lMpYKwYO6_QcWBti1wPKbjK; m_pixel_ratio=1; wd=1284x422; c_user={cookies.get('c_user', '')}; xs={cookies.get('xs', '')}"
328
- headers["Cookie"] = cookie_str
329
- response = requests.get("https://www.facebook.com/settings?tab=applications&ref=settings",headers=headers)
330
- apps_matches = re.findall(r'\",\"app_name\":\"([^\"]+)\",\"', response.text)
331
- linked_apps = list(set(apps_matches))
332
- return linked_apps
333
-
334
- import requests, re, json, time, os, random
335
- from typing import Optional, Dict, Any, Tuple
336
- from datetime import datetime
337
-
338
- class InstaResetTool:
339
- @staticmethod
340
- class InstaClient:
341
- def __init__(self):
342
- self.session = requests.Session()
343
- self.csrf_token = None
344
- self.response_history = []
345
- self.session.headers.update({
346
- "User-Agent": "Instagram 320.0.0.34.109 Android (33/13; 420dpi; 1080x2340; samsung; SM-A546B; a54x; exynos1380; en_US; 465123678)",
347
- 'X-IG-App-Startup-Country': 'US',
348
- 'X-Bloks-Version-Id': 'ce555e5500576acd8e84a66018f54a05720f2dce29f0bb5a1f97f0c10d6fac48',
349
- 'X-IG-App-ID': '567067343352427',
350
- 'X-IG-Connection-Type': 'WIFI',
351
- "Accept": "*/*",
352
- "Accept-Language": "en-US,en;q=0.9",
353
- 'accept-encoding': 'gzip, deflate',
354
- 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
355
- "Connection": "keep-alive",
356
- "Origin": "https://www.instagram.com",
357
- "Referer": "https://www.instagram.com/",
358
- })
359
-
360
- def cev1(self, text: str) -> Optional[str]:
361
- patterns = [
362
- r'"csrf_token":"(.*?)"',
363
- r'csrftoken=([a-zA-Z0-9]+)',
364
- ]
365
- for p in patterns:
366
- m = re.search(p, text)
367
- if m:
368
- self.csrf_token = m.group(1)
369
- self.session.headers["X-CSRFToken"] = self.csrf_token
370
- return self.csrf_token
371
- return None
372
-
373
- def cev2(self, url: str) -> Optional[requests.Response]:
374
- try:
375
- r = self.session.get(url, timeout=10)
376
- self.response_history.append({
377
- "timestamp": datetime.now().isoformat(),
378
- "url": url,
379
- "method": "GET",
380
- "status_code": r.status_code,
381
- "cookies": dict(self.session.cookies),
382
- "csrf_token": self.csrf_token
383
- })
384
- self.cev1(r.text)
385
- return r
386
- except Exception as e:
387
- self.response_history.append({
388
- "timestamp": datetime.now().isoformat(),
389
- "url": url,
390
- "method": "GET",
391
- "error": str(e),
392
- "cookies": dict(self.session.cookies)
393
- })
394
- return None
395
-
396
- def cev3(self, url: str, data=None, extra_headers=None):
397
- headers = self.session.headers.copy()
398
- if extra_headers:
399
- headers.update(extra_headers)
400
-
401
- try:
402
- r = self.session.post(url, data=data, headers=headers, timeout=10)
403
-
404
- response_data = {
405
- "timestamp": datetime.now().isoformat(),
406
- "url": url,
407
- "method": "POST",
408
- "status_code": r.status_code,
409
- "cookies": dict(self.session.cookies),
410
- "request_data": data,
411
- "content_length": len(r.content),
412
- "response_time": r.elapsed.total_seconds()
413
- }
414
-
415
- self.response_history.append(response_data)
416
-
417
- if r.status_code == 200 and len(r.content) > 100:
418
- return True, r, response_data
419
-
420
- return False, r, response_data
421
-
422
- except Exception as e:
423
- self.response_history.append({
424
- "timestamp": datetime.now().isoformat(),
425
- "url": url,
426
- "method": "POST",
427
- "error": str(e),
428
- "request_data": data,
429
- "cookies": dict(self.session.cookies)
430
- })
431
- return False, None, None
432
-
433
- @staticmethod
434
- def generate_jazoest(email_or_username: str) -> str:
435
- return "21885"
436
-
437
- @staticmethod
438
- def extract_instagram_info(response: requests.Response) -> Dict[str, Any]:
439
- info = {
440
- "raw_response": response.text if hasattr(response, 'text') else None,
441
- "content_length": len(response.content) if hasattr(response, 'content') else 0,
442
- "elapsed_time": response.elapsed.total_seconds() if hasattr(response, 'elapsed') else 0,
443
- "url": response.url if hasattr(response, 'url') else None,
444
- }
445
-
446
- if hasattr(response, 'headers'):
447
- headers = dict(response.headers)
448
- info["headers"] = headers
449
-
450
- instagram_headers = {}
451
- for key, value in headers.items():
452
- if any(ig_key in key.lower() for ig_key in ['ig', 'instagram', 'x-ig']):
453
- instagram_headers[key] = value
454
- info["instagram_headers"] = instagram_headers
455
-
456
- try:
457
- json_data = response.json()
458
- info["json_response"] = json_data
459
-
460
- if isinstance(json_data, dict):
461
- info["instagram_status"] = json_data.get("status", "unknown")
462
- info["instagram_message"] = json_data.get("message", json_data.get("error_message"))
463
- info["instagram_user_id"] = json_data.get("user_id", json_data.get("pk"))
464
- info["instagram_username"] = json_data.get("username")
465
- info["instagram_email"] = json_data.get("email")
466
- info["instagram_challenge_required"] = json_data.get("challenge_required", False)
467
- info["instagram_two_factor_required"] = json_data.get("two_factor_required", False)
468
- info["instagram_contact_point"] = json_data.get("contact_point")
469
- info["instagram_obfuscated_contact_point"] = json_data.get("obfuscated_contact_point")
470
-
471
- if "checkpoint_url" in json_data:
472
- info["checkpoint_required"] = True
473
- info["checkpoint_url"] = json_data.get("checkpoint_url")
474
- if "flow_render_type" in json_data:
475
- info["flow_type"] = json_data.get("flow_render_type")
476
-
477
- except:
478
- info["json_response"] = None
479
- info["raw_text"] = response.text[:500] + "..." if hasattr(response, 'text') and len(response.text) > 500 else response.text if hasattr(response, 'text') else None
480
-
481
- return info
482
-
483
- def reset_password(self, username: str) -> Dict[str, Any]:
484
- client = self.InstaClient()
485
-
486
- client.cev2("https://www.instagram.com/")
487
- time.sleep(random.uniform(0.1, 0.2))
488
-
489
- client.cev2("https://www.instagram.com/accounts/password/reset/")
490
-
491
- jazoest_value = self.generate_jazoest(username)
492
-
493
- payload = {
494
- "email_or_username": username,
495
- "jazoest": jazoest_value,
496
- }
497
-
498
- success, response, request_data = client.cev3(
499
- "https://www.instagram.com/api/v1/web/accounts/account_recovery_send_ajax/",
500
- data=payload,
501
- extra_headers={"X-Requested-With": "XMLHttpRequest"}
502
- )
503
-
504
- result = {
505
- "request_info": {
506
- "timestamp": datetime.now().isoformat(),
507
- "username": username,
508
- "jazoest": jazoest_value,
509
- "payload": payload,
510
- "endpoint": "https://www.instagram.com/api/v1/web/accounts/account_recovery_send_ajax/",
511
- "method": "POST"
512
- },
513
-
514
- "session_info": {
515
- "csrf_token": client.csrf_token,
516
- "cookies": dict(client.session.cookies),
517
- "user_agent": client.session.headers.get("User-Agent"),
518
- "app_id": client.session.headers.get("X-IG-App-ID"),
519
- "bloks_version": client.session.headers.get("X-Bloks-Version-Id"),
520
- },
521
-
522
- "request_history": client.response_history,
523
-
524
- "reset_response": {
525
- "success": success,
526
- "status_code": response.status_code if response else None,
527
- "instagram_info": self.extract_instagram_info(response) if response else None,
528
- },
529
-
530
- "response_analysis": {}
531
- }
532
-
533
- if response:
534
- analysis = {
535
- "is_successful": success,
536
- "is_instagram_response": response.status_code == 200 and len(response.content) > 100,
537
- "has_json": False,
538
- "instagram_status": None,
539
- "email_sent": False,
540
- "challenge_required": False,
541
- "user_exists": None,
542
- "possible_errors": []
543
- }
544
-
545
- try:
546
- json_data = response.json()
547
- analysis["has_json"] = True
548
- analysis["instagram_status"] = json_data.get("status")
549
- analysis["instagram_message"] = json_data.get("message")
550
-
551
- if json_data.get("status") == "ok" or json_data.get("message") in ["Email sent", "Password reset email sent"]:
552
- analysis["email_sent"] = True
553
-
554
- if json_data.get("status") == "ok":
555
- analysis["user_exists"] = True
556
- elif "user" in json_data.get("message", "").lower() or "account" in json_data.get("message", "").lower():
557
- analysis["user_exists"] = False
558
- analysis["possible_errors"].append("USER_NOT_FOUND")
559
-
560
- if json_data.get("challenge_required") or json_data.get("checkpoint_url"):
561
- analysis["challenge_required"] = True
562
- analysis["possible_errors"].append("CHALLENGE_REQUIRED")
563
-
564
- except:
565
- pass
566
-
567
- if response.status_code == 200:
568
- analysis["possible_errors"].append("NONE")
569
- elif response.status_code == 400:
570
- analysis["possible_errors"].append("BAD_REQUEST")
571
- elif response.status_code == 403:
572
- analysis["possible_errors"].append("FORBIDDEN")
573
- elif response.status_code == 429:
574
- analysis["possible_errors"].append("RATE_LIMIT")
575
- elif response.status_code >= 500:
576
- analysis["possible_errors"].append("SERVER_ERROR")
577
-
578
- result["response_analysis"] = analysis
579
-
580
- result["summary"] = {
581
- "username": username,
582
- "request_made": True,
583
- "instagram_responded": response is not None,
584
- "final_status": "SUCCESS" if success else "FAILED" if response else "ERROR",
585
- "email_possibly_sent": result.get("response_analysis", {}).get("email_sent", False),
586
- "user_likely_exists": result.get("response_analysis", {}).get("user_exists"),
587
- "timestamp_completed": datetime.now().isoformat(),
588
- "total_time": sum(item.get("response_time", 0) for item in client.response_history if "response_time" in item)
589
- }
590
-
591
- return result
592
-
593
- def get_full_response(self, username: str) -> Dict[str, Any]:
594
- return self.reset_password(username)
595
-
596
- def analyze_response_only(self, response_text: str) -> Dict[str, Any]:
597
- class MockResponse:
598
- def __init__(self, text):
599
- self.text = text
600
- self.content = text.encode('utf-8') if text else b''
601
- self.headers = {}
602
- self.status_code = 200
603
- self.elapsed = type('obj', (object,), {'total_seconds': lambda: 0})()
604
- self.url = "https://www.instagram.com/api/v1/web/accounts/account_recovery_send_ajax/"
605
-
606
- mock_response = MockResponse(response_text)
607
- return self.extract_instagram_info(mock_response)
608
-
609
-
610
- def cev6(usernames) -> Dict[str, Any]:
611
- tool = InstaResetTool()
612
-
613
- if isinstance(usernames, str):
614
- username = usernames
615
- elif isinstance(usernames, list) and len(usernames) > 0:
616
- username = usernames[0]
617
- else:
618
- return {"status": "error", "message": "Invalid username input"}
619
-
620
- return tool.reset_password(username)
621
-
622
-
623
- def reset_password(username: str) -> Dict[str, Any]:
624
- tool = InstaResetTool()
625
- return tool.reset_password(username)
626
-
627
- # إضافة الدوال الناقصة التي يحاول المستخدم استيرادها
628
- def analyze_instagram_only(response_text: str) -> Dict[str, Any]:
629
- """Alias for analyze_response_only for compatibility"""
630
- tool = InstaResetTool()
631
- return tool.analyze_response_only(response_text)
632
-
633
- def analyze_instagram_json(json_str: str) -> Dict[str, Any]:
634
- """Analyze Instagram JSON response"""
635
- tool = InstaResetTool()
636
- return tool.analyze_response_only(json_str)
321
+ def get_linked_apps(cookies_input):
322
+ session = requests.Session()
323
+ if isinstance(cookies_input, dict):coki = cookies_input
324
+ elif isinstance(cookies_input, str):
325
+ coki = {}
326
+ cleaned = ';'.join([p.strip() for p in cookies_input.split(';') if p.strip()])
327
+ for part in cleaned.split(';'):
328
+ if '=' not in part:
329
+ continue
330
+ key, val = part.split('=', 1)
331
+ coki[key.strip()] = val.strip()
332
+ else:return ["خطأ في صيغة الكوكيز"]
333
+ ua = 'NokiaX2-01/5.0 (08.35) Profile/MIDP-2.1 Configuration/CLDC-1.1 Mozilla/5.0 (Linux; Android 9; SH-03J) AppleWebKit/537.36 (KHTML, like Gecko) Safari/420+'
334
+ headers = {'user-agent': ua}
335
+ try:rr1 = session.get('https://m.facebook.com/settings/apps/tabbed/?tab=active', cookies=coki, headers=headers, timeout=12).text
336
+ except:rr1 = ""
337
+ try:rr2 = session.get('https://m.facebook.com/settings/apps/tabbed/?tab=inactive', cookies=coki, headers=headers, timeout=12).text
338
+ except:rr2 = ""
339
+ output = []
340
+ if 'tidak memiliki aplikasi' in rr1.lower() or 'no active apps' in rr1.lower():output.append("No active apps")
341
+ else:
342
+ apps_active = re.findall(r'data-testid="app_info_text">([^<]+)</span>', rr1)
343
+ dates_active = re.findall(r'(?:تمت الإضافة في|Added on|Ditambahkan pada|Ajouté le|Dodano dnia)\s*([^<]+)</p>', rr1)
344
+ if not apps_active:output.append("No active apps found")
345
+ else:
346
+ for i, app in enumerate(apps_active):
347
+ app_clean = app.strip()
348
+ try:date_clean = dates_active[i].strip()
349
+ except IndexError:date_clean = "غير معروف"
350
+ output.append(f"[{i+1}] {app_clean} - {date_clean}")
351
+ lower_rr2 = rr2.lower()
352
+ if 'kedaluwarsa' in lower_rr2 and 'tidak memiliki' in lower_rr2:output.append("No inactive/expired apps")
353
+ else:
354
+ apps_inactive = re.findall(r'data-testid="app_info_text">([^<]+)</span>', rr2)
355
+ dates_raw = re.findall(r'<p[^>]*>(?:Kedaluwarsa pada|انتهت الصلاحية في|منتهية الصلاحية في|Expired on)[^<]*</p>', rr2)
356
+ dates_inactive = [re.sub(r'<[^>]+>', '', d).strip() for d in dates_raw]
357
+ if not apps_inactive:output.append("No inactive/expired apps found")
358
+ else:
359
+ for i, app in enumerate(apps_inactive):
360
+ app_clean = app.strip()
361
+ try:date_clean = dates_inactive[i].strip()
362
+ except IndexError:date_clean = "غير معروف"
363
+ output.append(f"[{i+1}] {app_clean} - {date_clean}")
364
+ if not output:output.append("لا توجد بيانات متاحة")
365
+ return output
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: odaislib
3
- Version: 1.0.8
3
+ Version: 1.0.9
4
4
  Summary: Facebook Authentication Library with multiple login methods
5
5
  Home-page:
6
6
  Author: Odai
@@ -3,7 +3,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
3
3
  long_description = fh.read()
4
4
  setup(
5
5
  name="odaislib",
6
- version="1.0.8",
6
+ version="1.0.9",
7
7
  author="Odai",
8
8
  author_email="odaiobeidat00@gmail.com",
9
9
  description="Facebook Authentication Library with multiple login methods",
File without changes
File without changes