Itssuman1808

STUDY FEVER

Jun 19th, 2021
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 44.16 KB | None | 0 0
  1. /* ░██████╗░██████╗░██╗░░░░░░░░██╗░██████╗░░░░█████╗░██████╗░░██████╗░
  2. ██╔════╝░██╔══██╗██║░░░░░░░░██║██╔════╝░░░██╔══██╗██╔══██╗██╔════╝░
  3. ██║░░██╗░██║░░██║██║░░░░░░░░██║╚█████╗░░░░██║░░██║██████╔╝██║░░██╗░
  4. ██║░░╚██╗██║░░██║██║░░░██╗░░██║░╚═══██╗░░░██║░░██║██╔══██╗██║░░╚██╗
  5. ╚██████╔╝██████╔╝██║██╗╚█████╔╝██████╔╝██╗╚█████╔╝██║░░██║╚██████╔╝
  6. ░╚═════╝░╚═════╝░╚═╝╚═╝░╚════╝░╚═════╝░╚═╝░╚════╝░╚═╝░░╚═╝░╚═════╝░
  7. v 2.0.18
  8. A Script Redesigned by Parveen Bhadoo from GOIndex at https://github.com/ParveenBhadooOfficial/Google-Drive-Index */
  9.  
  10. // add multiple serviceaccounts as {}, {}, {}, random account will be selected by each time app is opened.
  11. const serviceaccounts = [
  12. {}
  13. ];
  14. const randomserviceaccount = serviceaccounts[Math.floor(Math.random()*serviceaccounts.length)];
  15.  
  16. const authConfig = {
  17. "siteName": "Sherspect", // Website name
  18. "client_id": "746239575955-oao9hkv614p8glrqpvuh5i8mqfoq145b.apps.googleusercontent.com", // Client id from Google Cloud Console
  19. "client_secret": "u5a1CSY5pNjdD2tGTU93TTnI", // Client Secret from Google Cloud Console
  20. "refresh_token": "1//09FdHyQH3jXWfCgYIARAAGAkSNwF-L9IrUD3OFXjn-gr0d-FDwCKQkslhveaKYhT72l0B3NT50AoGeFgNLng0gnSeaP59EEHxWUs", // Authorize token
  21. "service_account": false, // true if you're using Service Account instead of user account
  22. "service_account_json": randomserviceaccount, // don't touch this one
  23. "files_list_page_size": 50,
  24. "search_result_list_page_size": 50,
  25. "enable_cors_file_down": false,
  26. "enable_password_file_verify": true, // support for .password file
  27. "roots":[
  28. {
  29. "id": "0AP3SZ8AczH2qUk9PVA",
  30. "name": "JAI MAHAKAAL | v1",
  31. "protect_file_link": true,
  32. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  33. },
  34. {
  35. "id": "0AIGIT4ioLQASUk9PVA",
  36. "name": "JAI MAHAKAAL | v2",
  37. "protect_file_link": true,
  38. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  39. },
  40. {
  41. "id": "0AM1xB9LYlPUVUk9PVA",
  42. "name": "JAI MAHAKAAL | v3",
  43. "protect_file_link": true,
  44. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  45. },
  46. {
  47. "id": "0AFU_QV5vBWQ4Uk9PVA",
  48. "name": "JAI MAHAKAAL | v4",
  49. "protect_file_link": true,
  50. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  51. },
  52. {
  53. "id": "0AECdHSJldAHuUk9PVA",
  54. "name": "JAI MAHAKAAL | v5",
  55. "protect_file_link": true,
  56. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  57. },
  58. {
  59. "id": "0AKJEVcsZp3l7Uk9PVA",
  60. "name": "JAI MAHAKAAL | v6",
  61. "protect_file_link": true,
  62. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  63. },
  64. {
  65. "id": "0AGdenBzHpLn2Uk9PVA",
  66. "name": "JAI MAHAKAAL | v7",
  67. "protect_file_link": true,
  68. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  69. },
  70. {
  71. "id": "1W4eI9ionHGQu8m74bCFX6KDxsuQTMsgP",
  72. "name": "ENTERTAINMENT DRIVE 😍",
  73. "protect_file_link": true,
  74. "auth": {"ssf":"ssf"} /* Remove double slash before "auth" to activate id password protection */
  75. },
  76. ]};
  77.  
  78.  
  79. /*
  80. ███████╗██████╗░██╗████████╗  ████████╗██╗░░██╗███████╗░██████╗███████╗
  81. ██╔════╝██╔══██╗██║╚══██╔══╝  ╚══██╔══╝██║░░██║██╔════╝██╔════╝██╔════╝
  82. █████╗░░██║░░██║██║░░░██║░░░  ░░░██║░░░███████║█████╗░░╚█████╗░█████╗░░
  83. ██╔══╝░░██║░░██║██║░░░██║░░░  ░░░██║░░░██╔══██║██╔══╝░░░╚═══██╗██╔══╝░░
  84. ███████╗██████╔╝██║░░░██║░░░  ░░░██║░░░██║░░██║███████╗██████╔╝███████╗
  85. ╚══════╝╚═════╝░╚═╝░░░╚═╝░░░  ░░░╚═╝░░░╚═╝░░╚═╝╚══════╝╚═════╝░╚══════╝
  86.  
  87. ██╗░░░██╗░█████╗░██╗░░░░░██╗░░░██╗███████╗░██████╗
  88. ██║░░░██║██╔══██╗██║░░░░░██║░░░██║██╔════╝██╔════╝
  89. ╚██╗░██╔╝███████║██║░░░░░██║░░░██║█████╗░░╚█████╗░
  90. ░╚████╔╝░██╔══██║██║░░░░░██║░░░██║██╔══╝░░░╚═══██╗
  91. ░░╚██╔╝░░██║░░██║███████╗╚██████╔╝███████╗██████╔╝
  92. ░░░╚═╝░░░╚═╝░░╚═╝╚══════╝░╚═════╝░╚══════╝╚═════╝░*/
  93.  
  94. const uiConfig = {
  95. "theme": "cyborg", // switch between themes, default set to cyborg, select from https://github.com/ParveenBhadooOfficial/Google-Drive-Index#themes
  96. "version": "2.0.17-alpha.7", // don't touch this one. get latest code using generator at https://generator.driveindex.ga
  97. // If you're using Image then set to true, If you want text then set it to false
  98. "logo_image": false, // true if you're using image link in next option.
  99. "logo_height": "", // only if logo_image is true
  100. "logo_width": "100px", // only if logo_image is true
  101. "favicon": "https://cdn.jsdelivr.net/gh/ParveenBhadooOfficial/Google-Drive-Index@2.0.17-alpha.7/images/favicon.ico",
  102. // if logo is true then link otherwise just text for name
  103. "logo_link_name": "Bom Sankar 😎 It’s better to be a lion for a day than a sheep all your life.",
  104. "fixed_header": true, // If you want the footer to be flexible or fixed.
  105. "header_padding": "60", // Value 60 for fixed header, Value 20 for flexible header. Required to be changed accordingly in some themes.
  106. "fixed_footer": false, // If you want the footer to be flexible or fixed.
  107. "header_style_class": "navbar-dark bg-primary", // navbar-dark bg-primary || navbar-dark bg-dark || navbar-light bg-light
  108. "footer_style_class": "bg-primary", // bg-primary || bg-dark || bg-light
  109. "css_a_tag_color": "white", // Color Name or Hex Code eg. #ffffff
  110. "css_p_tag_color": "white", // Color Name or Hex Code eg. #ffffff
  111. "folder_text_color": "white", // Color Name or Hex Code eg. #ffffff
  112. "loading_spinner_class": "text-light", // https://getbootstrap.com/docs/5.0/components/spinners/#colors
  113. "search_button_class": "btn-outline-success", // https://getbootstrap.com/docs/5.0/components/buttons/#examples
  114. "path_nav_alert_class": "alert alert-primary", // https://getbootstrap.com/docs/4.0/components/alerts/#examples
  115. "file_view_alert_class": "alert alert-danger", // https://getbootstrap.com/docs/4.0/components/alerts/#examples
  116. "file_count_alert_class": "alert alert-secondary", // https://getbootstrap.com/docs/4.0/components/alerts/#examples
  117. "contact_link": "https://GOOGLE.COM", // Link to Contact Button on Menu
  118. "copyright_year": "2050", // year of copyright, can be anything like 2015 - 2020 or just 2020
  119. "company_name": "BOMSHIV 🎭 itsSuman 😎", // Name next to copyright
  120. "company_link": "https://GOOGLE.COM", // link of copyright name
  121. "credit": false, // Set this to true to give us credit
  122. "display_size": true, // Set this to false to hide display file size
  123. "display_time": true, // Set this to false to hide display modified time for folder and files
  124. "display_download": true, // Set this to false to hide download icon for folder and files on main index
  125. "disable_player": false, // Set this to true to hide audio and video players
  126. "disable_video_download": false, // Remove Download, Copy Button on Videos
  127. "second_domain_for_dl": false, // If you want to display other URL for Downloading to protect your main domain.
  128. "downloaddomain": "https://testing.fetchgoogleapi.workers.dev", // If "second_domain_for_dl": true then enter downloaddomain otherwise keep empty. eg. https://workers.workersname.workers.dev No Trailing '/'
  129. "poster": "https://cdn.jsdelivr.net/gh/ParveenBhadooOfficial/Google-Drive-Index@2.0.10/images/poster.jpg", // Video poster URL or see Readme to how to load from Drive
  130. "audioposter": "https://cdn.jsdelivr.net/gh/ParveenBhadooOfficial/Google-Drive-Index@2.0.10/images/music.jpg", // Video poster URL or see Readme to how to load from Drive
  131. "jsdelivr_cdn_src": "https://cdn.jsdelivr.net/gh/ParveenBhadooOfficial/Google-Drive-Index", // If Project is Forked, then enter your Github repo
  132. "render_head_md": true, // Render Head.md
  133. "render_readme_md": true, // Render Readme.md
  134. "display_drive_link": false, // This will add a Link Button to Google Drive of that particular file.
  135. "plyr_io_version": "3.6.4", // Change plyr.io version in future when needed.
  136. "unauthorized_owner_link": "https://telegram.dog/Telegram", // Unauthorized Error Page Link to Owner
  137. "unauthorized_owner_email": "username@googlemail.com", // Unauthorized Error Page Owner Email
  138. "arc_code": "jf2h" // arc.io Integraion Code, get yours from https://portal.arc.io
  139. };
  140.  
  141.  
  142. /*
  143. ██████╗░░█████╗░  ███╗░░██╗░█████╗░████████╗  ███████╗██████╗░██╗████████╗
  144. ██╔══██╗██╔══██╗  ████╗░██║██╔══██╗╚══██╔══╝  ██╔════╝██╔══██╗██║╚══██╔══╝
  145. ██║░░██║██║░░██║  ██╔██╗██║██║░░██║░░░██║░░░  █████╗░░██║░░██║██║░░░██║░░░
  146. ██║░░██║██║░░██║  ██║╚████║██║░░██║░░░██║░░░  ██╔══╝░░██║░░██║██║░░░██║░░░
  147. ██████╔╝╚█████╔╝  ██║░╚███║╚█████╔╝░░░██║░░░  ███████╗██████╔╝██║░░░██║░░░
  148. ╚═════╝░░╚════╝░  ╚═╝░░╚══╝░╚════╝░░░░╚═╝░░░  ╚══════╝╚═════╝░╚═╝░░░╚═╝░░░
  149.  
  150. ██████╗░███████╗██╗░░░░░░█████╗░░██╗░░░░░░░██╗
  151. ██╔══██╗██╔════╝██║░░░░░██╔══██╗░██║░░██╗░░██║
  152. ██████╦╝█████╗░░██║░░░░░██║░░██║░╚██╗████╗██╔╝
  153. ██╔══██╗██╔══╝░░██║░░░░░██║░░██║░░████╔═████║░
  154. ██████╦╝███████╗███████╗╚█████╔╝░░╚██╔╝░╚██╔╝░
  155. ╚═════╝░╚══════╝╚══════╝░╚════╝░░░░╚═╝░░░╚═╝░░*/
  156.  
  157. // DON'T TOUCH BELOW THIS UNLESS YOU KNOW WHAT YOU'RE DOING
  158. var gds = [];
  159.  
  160. function html(current_drive_order = 0, model = {}) {
  161. return `<!DOCTYPE html>
  162. <html>
  163. <head>
  164. <meta charset="utf-8">
  165. <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no"/>
  166. <title>HAR HAR MAHADEV 🎭</title>
  167. <script async src="https://arc.io/widget.min.js#${uiConfig.arc_code}"></script>
  168. <meta name="robots" content="noindex" />
  169. <link rel="icon" href="${uiConfig.favicon}">
  170. <script>
  171. window.drive_names = JSON.parse('${JSON.stringify(authConfig.roots.map(it => it.name))}');
  172. window.MODEL = JSON.parse('${JSON.stringify(model)}');
  173. window.current_drive_order = ${current_drive_order};
  174. window.UI = JSON.parse('${JSON.stringify(uiConfig)}');
  175. </script>
  176. <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
  177. <link rel="stylesheet" href="https://cdn.plyr.io/${uiConfig.plyr_io_version}/plyr.css" />
  178. <link href="https://cdn.jsdelivr.net/npm/bootswatch@5.0.0/dist/${uiConfig.theme}/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
  179. <style>
  180. a {
  181. color: ${uiConfig.css_a_tag_color};
  182. }
  183. p {
  184. color: ${uiConfig.css_p_tag_color};
  185. }
  186. </style>
  187. <script src="${uiConfig.jsdelivr_cdn_src}@${uiConfig.version}/js/app.min.js"></script>
  188. <script src="https://cdn.jsdelivr.net/gh/mozilla/pdf.js@gh-pages/build/pdf.js"></script>
  189. <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
  190. </head>
  191. <body>
  192. </body>
  193. <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous"></script>
  194. <script src="https://cdn.plyr.io/${uiConfig.plyr_io_version}/plyr.polyfilled.js"></script>
  195. </html>`;
  196. };
  197.  
  198. const unauthorized = `<html>
  199. <head><title>401 Unauthorized</title></head>
  200. <body>
  201. <center><h1>401 Unauthorized</h1></center>
  202. <hr><center>gdi.js.org/2.0.18</center>
  203. <hr><center>Please contact <a href="${uiConfig.unauthorized_owner_link}">Site Owner</a> at ${uiConfig.unauthorized_owner_email}</center>
  204. </body>
  205. </html>`
  206.  
  207. const not_found = `<html>
  208. <head><title>404 File Not Found</title></head>
  209. <body>
  210. <center><h1>404 File Not Found</h1></center>
  211. <hr><center>gdi.js.org/2.0.18</center>
  212. <hr><center>Please contact <a href="${uiConfig.unauthorized_owner_link}">Site Owner</a> at ${uiConfig.unauthorized_owner_email}</center>
  213. </body>
  214. </html>`
  215.  
  216.  
  217. const SearchFunction = {
  218. formatSearchKeyword: function(keyword) {
  219. let nothing = "";
  220. let space = " ";
  221. if (!keyword) return nothing;
  222. return keyword.replace(/(!=)|['"=<>/\\:]/g, nothing)
  223. .replace(/[,,|(){}]/g, space)
  224. .trim()
  225. }
  226.  
  227. };
  228.  
  229. const DriveFixedTerms = new(class {
  230. default_file_fields = 'parents,id,name,mimeType,modifiedTime,createdTime,fileExtension,size';
  231. gd_root_type = {
  232. user_drive: 0,
  233. share_drive: 1,
  234. sub_folder: 2
  235. };
  236. folder_mime_type = 'application/vnd.google-apps.folder';
  237. })();
  238.  
  239. const JSONWebToken = {
  240. header: {
  241. alg: 'RS256',
  242. typ: 'JWT'
  243. },
  244. importKey: async function(pemKey) {
  245. var pemDER = this.textUtils.base64ToArrayBuffer(pemKey.split('\n').map(s => s.trim()).filter(l => l.length && !l.startsWith('---')).join(''));
  246. return crypto.subtle.importKey('pkcs8', pemDER, {
  247. name: 'RSASSA-PKCS1-v1_5',
  248. hash: 'SHA-256'
  249. }, false, ['sign']);
  250. },
  251. createSignature: async function(text, key) {
  252. const textBuffer = this.textUtils.stringToArrayBuffer(text);
  253. return crypto.subtle.sign('RSASSA-PKCS1-v1_5', key, textBuffer)
  254. },
  255. generateGCPToken: async function(serviceAccount) {
  256. const iat = parseInt(Date.now() / 1000);
  257. var payload = {
  258. "iss": serviceAccount.client_email,
  259. "scope": "https://www.googleapis.com/auth/drive",
  260. "aud": "https://oauth2.googleapis.com/token",
  261. "exp": iat + 3600,
  262. "iat": iat
  263. };
  264. const encPayload = btoa(JSON.stringify(payload));
  265. const encHeader = btoa(JSON.stringify(this.header));
  266. var key = await this.importKey(serviceAccount.private_key);
  267. var signed = await this.createSignature(encHeader + "." + encPayload, key);
  268. return encHeader + "." + encPayload + "." + this.textUtils.arrayBufferToBase64(signed).replace(/\//g, '_').replace(/\+/g, '-');
  269. },
  270. textUtils: {
  271. base64ToArrayBuffer: function(base64) {
  272. var binary_string = atob(base64);
  273. var len = binary_string.length;
  274. var bytes = new Uint8Array(len);
  275. for (var i = 0; i < len; i++) {
  276. bytes[i] = binary_string.charCodeAt(i);
  277. }
  278. return bytes.buffer;
  279. },
  280. stringToArrayBuffer: function(str) {
  281. var len = str.length;
  282. var bytes = new Uint8Array(len);
  283. for (var i = 0; i < len; i++) {
  284. bytes[i] = str.charCodeAt(i);
  285. }
  286. return bytes.buffer;
  287. },
  288. arrayBufferToBase64: function(buffer) {
  289. let binary = '';
  290. let bytes = new Uint8Array(buffer);
  291. let len = bytes.byteLength;
  292. for (let i = 0; i < len; i++) {
  293. binary += String.fromCharCode(bytes[i]);
  294. }
  295. return btoa(binary);
  296. }
  297. }
  298. };
  299.  
  300. addEventListener('fetch', event => {
  301. event.respondWith(handleRequest(event.request));
  302. });
  303.  
  304. async function handleRequest(request) {
  305. if (gds.length === 0) {
  306. for (let i = 0; i < authConfig.roots.length; i++) {
  307. const gd = new googleDrive(authConfig, i);
  308. await gd.init();
  309. gds.push(gd)
  310. }
  311. let tasks = [];
  312. gds.forEach(gd => {
  313. tasks.push(gd.initRootType());
  314. });
  315. for (let task of tasks) {
  316. await task;
  317. }
  318. }
  319.  
  320. let gd;
  321. let url = new URL(request.url);
  322. let path = url.pathname;
  323.  
  324. function redirectToIndexPage() {
  325. return new Response('', {
  326. status: 301,
  327. headers: {
  328. 'Location': `${url.origin}/0:/`
  329. }
  330. });
  331. }
  332.  
  333. if (path == '/') return redirectToIndexPage();
  334. if (path.toLowerCase() == '/arc-sw.js') {
  335. return fetch("https://arc.io/arc-sw.js")
  336. } else if (path.toLowerCase() == '/admin') {
  337. return Response.redirect("https://bit.ly/3sAxYwr", 301)
  338. } else if (path.toLowerCase() == '/update') {
  339. return Response.redirect("https://generator.driveindex.ga", 301)
  340. }
  341.  
  342. const command_reg = /^\/(?<num>\d+):(?<command>[a-zA-Z0-9]+)(\/.*)?$/g;
  343. const match = command_reg.exec(path);
  344. if (match) {
  345. const num = match.groups.num;
  346. const order = Number(num);
  347. if (order >= 0 && order < gds.length) {
  348. gd = gds[order];
  349. } else {
  350. return redirectToIndexPage()
  351. }
  352. for (const r = gd.basicAuthResponse(request); r;) return r;
  353. const command = match.groups.command;
  354. if (command === 'search') {
  355. if (request.method === 'POST') {
  356. return handleSearch(request, gd);
  357. } else {
  358. const params = url.searchParams;
  359. return new Response(html(gd.order, {
  360. q: params.get("q").replace(/'/g, "").replace(/"/g, "") || '',
  361. is_search_page: true,
  362. root_type: gd.root_type
  363. }), {
  364. status: 200,
  365. headers: {
  366. 'Content-Type': 'text/html; charset=utf-8'
  367. }
  368. });
  369. }
  370. } else if (command === 'id2path' && request.method === 'POST') {
  371. return handleId2Path(request, gd)
  372. }
  373. }
  374.  
  375. const common_reg = /^\/\d+:\/.*$/g;
  376. try {
  377. if (!path.match(common_reg)) {
  378. return redirectToIndexPage();
  379. }
  380. let split = path.split("/");
  381. let order = Number(split[1].slice(0, -1));
  382. if (order >= 0 && order < gds.length) {
  383. gd = gds[order];
  384. } else {
  385. return redirectToIndexPage()
  386. }
  387. } catch (e) {
  388. return redirectToIndexPage()
  389. }
  390.  
  391. const basic_auth_res = gd.basicAuthResponse(request);
  392.  
  393. path = path.replace(gd.url_path_prefix, '') || '/';
  394. if (request.method == 'POST') {
  395. return basic_auth_res || apiRequest(request, gd);
  396. }
  397.  
  398. let action = url.searchParams.get('a');
  399.  
  400. if (path.substr(-1) == '/' || action != null) {
  401. return basic_auth_res || new Response(html(gd.order, {
  402. root_type: gd.root_type
  403. }), {
  404. status: 200,
  405. headers: {
  406. 'Content-Type': 'text/html; charset=utf-8'
  407. }
  408. });
  409. } else {
  410. if (path.split('/').pop().toLowerCase() == ".password") {
  411. return basic_auth_res || new Response("", {
  412. status: 404
  413. });
  414. }
  415. let file = await gd.file(path);
  416. let range = request.headers.get('Range');
  417. const inline_down = 'true' === url.searchParams.get('inline');
  418. if (gd.root.protect_file_link && basic_auth_res) return basic_auth_res;
  419. return gd.down(file?.id, range, inline_down);
  420. }
  421. }
  422.  
  423. function gdiencode(str) {
  424. var gdijsorg_0x40df = ['1KzJBAK', '1697708zMrtEu', '295396TasIvj', '21011Eyuayv', '1217593CxovUD', 'fromCharCode', '143062xekFCR', 'replace', '74bcHwvq', '73939wlqHSM', '2CBdqkc', '1712527AcNPoP'];
  425. var gdijsorg_0x5556bb = gdijsorg_0x56b1;
  426. (function(_0x3f3911, _0x38bce9) {
  427. var _0x32440e = gdijsorg_0x56b1;
  428. while (!![]) {
  429. try {
  430. var _0x2cab6f = -parseInt(_0x32440e(0xb3)) + -parseInt(_0x32440e(0xb7)) * -parseInt(_0x32440e(0xb6)) + -parseInt(_0x32440e(0xaf)) * -parseInt(_0x32440e(0xad)) + -parseInt(_0x32440e(0xb1)) + parseInt(_0x32440e(0xae)) + parseInt(_0x32440e(0xac)) + parseInt(_0x32440e(0xb0)) * -parseInt(_0x32440e(0xb5));
  431. if (_0x2cab6f === _0x38bce9) break;
  432. else _0x3f3911['push'](_0x3f3911['shift']());
  433. } catch (_0x34d506) {
  434. _0x3f3911['push'](_0x3f3911['shift']());
  435. }
  436. }
  437. }(gdijsorg_0x40df, 0xe5038));
  438.  
  439. function gdijsorg_0x56b1(_0x1ccc20, _0x1596c4) {
  440. _0x1ccc20 = _0x1ccc20 - 0xac;
  441. var _0x40df0f = gdijsorg_0x40df[_0x1ccc20];
  442. return _0x40df0f;
  443. }
  444. return btoa(encodeURIComponent(str)[gdijsorg_0x5556bb(0xb4)](/%([0-9A-F]{2})/g, function toSolidBytes(_0xe8cc7f, _0x12410f) {
  445. var _0x1cce23 = gdijsorg_0x5556bb;
  446. return String[_0x1cce23(0xb2)]('0x' + _0x12410f);
  447. }));
  448. }
  449.  
  450. async function apiRequest(request, gd) {
  451. let url = new URL(request.url);
  452. let path = url.pathname;
  453. path = path.replace(gd.url_path_prefix, '') || '/';
  454.  
  455. let option = {
  456. status: 200,
  457. headers: {
  458. 'Access-Control-Allow-Origin': '*'
  459. }
  460. }
  461.  
  462. if (path.substr(-1) == '/') {
  463. let form = await request.formData();
  464. let deferred_list_result = gd.list(path, form.get('page_token'), Number(form.get('page_index')));
  465.  
  466. if (authConfig['enable_password_file_verify']) {
  467. let password = await gd.password(path);
  468. // console.log("dir password", password);
  469. if (password && password.replace("\n", "") !== form.get('password')) {
  470. let html = `Y29kZWlzcHJvdGVjdGVk=0Xfi4icvJnclBCZy92dzNXYwJCI6ISZnF2czVWbiwSMwQDI6ISZk92YisHI6IicvJnclJyeYmFzZTY0aXNleGNsdWRlZA==`;
  471. return new Response(html, option);
  472. }
  473. }
  474.  
  475. let list_result = await deferred_list_result;
  476. return new Response(rewrite(gdiencode(JSON.stringify(list_result), option)));
  477. } else {
  478. let file = await gd.file(path);
  479. let range = request.headers.get('Range');
  480. return new Response(rewrite(gdiencode(JSON.stringify(file))));
  481. }
  482. }
  483.  
  484. // deal with search
  485. async function handleSearch(request, gd) {
  486. const option = {
  487. status: 200,
  488. headers: {
  489. 'Access-Control-Allow-Origin': '*'
  490. }
  491. };
  492. let form = await request.formData();
  493. let search_result = await
  494. gd.search(form.get('q') || '', form.get('page_token'), Number(form.get('page_index')));
  495. return new Response(rewrite(gdiencode(JSON.stringify(search_result), option)));
  496. }
  497.  
  498. async function handleId2Path(request, gd) {
  499. const option = {
  500. status: 200,
  501. headers: {
  502. 'Access-Control-Allow-Origin': '*'
  503. }
  504. };
  505. let form = await request.formData();
  506. let path = await gd.findPathById(form.get('id'));
  507. return new Response(path || '', option);
  508. }
  509.  
  510. class googleDrive {
  511. constructor(authConfig, order) {
  512. this.order = order;
  513. this.root = authConfig.roots[order];
  514. this.root.protect_file_link = this.root.protect_file_link || false;
  515. this.url_path_prefix = `/${order}:`;
  516. this.authConfig = authConfig;
  517. this.paths = [];
  518. this.files = [];
  519. this.passwords = [];
  520. this.id_path_cache = {};
  521. this.id_path_cache[this.root['id']] = '/';
  522. this.paths["/"] = this.root['id'];
  523. }
  524. async init() {
  525. await this.accessToken();
  526. if (authConfig.user_drive_real_root_id) return;
  527. const root_obj = await (gds[0] || this).findItemById('root');
  528. if (root_obj && root_obj.id) {
  529. authConfig.user_drive_real_root_id = root_obj.id
  530. }
  531. }
  532.  
  533. async initRootType() {
  534. const root_id = this.root['id'];
  535. const types = DriveFixedTerms.gd_root_type;
  536. if (root_id === 'root' || root_id === authConfig.user_drive_real_root_id) {
  537. this.root_type = types.user_drive;
  538. } else {
  539. const obj = await this.getShareDriveObjById(root_id);
  540. this.root_type = obj ? types.share_drive : types.sub_folder;
  541. }
  542. }
  543.  
  544. basicAuthResponse(request) {
  545. const auth = this.root.auth || '',
  546. _401 = new Response(unauthorized, {
  547. headers: {
  548. 'WWW-Authenticate': `Basic realm="goindex:drive:${this.order}"`,
  549. 'content-type': 'text/html;charset=UTF-8'
  550. },
  551. status: 401
  552. });
  553. if (auth) {
  554. const _auth = request.headers.get('Authorization')
  555. if (_auth) {
  556. const [received_user, received_pass] = atob(_auth.split(' ').pop()).split(':');
  557. if (auth.hasOwnProperty(received_user)) {
  558. if (auth[received_user] == received_pass) {
  559. return null;
  560. } else return _401;
  561. } else return _401;
  562. }
  563. } else return null;
  564. return _401;
  565. }
  566.  
  567. async down(id, range = '', inline = false) {
  568. let url = `https://www.googleapis.com/drive/v3/files/${id}?alt=media`;
  569. let requestOption = await this.requestOption();
  570. requestOption.headers['Range'] = range;
  571. let res = await fetch(url, requestOption);
  572. if (res.ok) {
  573. const {
  574. headers
  575. } = res = new Response(res.body, res)
  576. this.authConfig.enable_cors_file_down && headers.append('Access-Control-Allow-Origin', '*');
  577. inline === true && headers.set('Content-Disposition', 'inline');
  578. return res;
  579. }
  580. else if(res.status == 404){
  581. return new Response(not_found, {
  582. status: 404,
  583. headers: {
  584. "content-type": "text/html;charset=UTF-8",
  585. },
  586. })
  587. }
  588. else {
  589. const res = await fetch(`${uiConfig.jsdelivr_cdn_src}@master/assets/DownloadError.html`);
  590. return new Response(await res.text(), {
  591. headers: {
  592. "content-type": "text/html;charset=UTF-8",
  593. },
  594. })
  595. }
  596. }
  597.  
  598. async file(path) {
  599. if (typeof this.files[path] == 'undefined') {
  600. this.files[path] = await this._file(path);
  601. }
  602. return this.files[path];
  603. }
  604.  
  605. async _file(path) {
  606. let arr = path.split('/');
  607. let name = arr.pop();
  608. name = decodeURIComponent(name).replace(/\'/g, "\\'");
  609. let dir = arr.join('/') + '/';
  610. // console.log(name, dir);
  611. let parent = await this.findPathId(dir);
  612. // console.log(parent);
  613. let url = 'https://www.googleapis.com/drive/v3/files';
  614. let params = {
  615. 'includeItemsFromAllDrives': true,
  616. 'supportsAllDrives': true
  617. };
  618. params.q = `'${parent}' in parents and name = '${name}' and trashed = false`;
  619. params.fields = "files(id, name, mimeType, size ,createdTime, modifiedTime, iconLink, thumbnailLink)";
  620. url += '?' + this.enQuery(params);
  621. let requestOption = await this.requestOption();
  622. let response = await fetch(url, requestOption);
  623. let obj = await response.json();
  624. // console.log(obj);
  625. return obj.files[0];
  626. }
  627.  
  628. async list(path, page_token = null, page_index = 0) {
  629. if (this.path_children_cache == undefined) {
  630. // { <path> :[ {nextPageToken:'',data:{}}, {nextPageToken:'',data:{}} ...], ...}
  631. this.path_children_cache = {};
  632. }
  633.  
  634. if (this.path_children_cache[path] &&
  635. this.path_children_cache[path][page_index] &&
  636. this.path_children_cache[path][page_index].data
  637. ) {
  638. let child_obj = this.path_children_cache[path][page_index];
  639. return {
  640. nextPageToken: child_obj.nextPageToken || null,
  641. curPageIndex: page_index,
  642. data: child_obj.data
  643. };
  644. }
  645.  
  646. let id = await this.findPathId(path);
  647. let result = await this._ls(id, page_token, page_index);
  648. let data = result.data;
  649. if (result.nextPageToken && data.files) {
  650. if (!Array.isArray(this.path_children_cache[path])) {
  651. this.path_children_cache[path] = []
  652. }
  653. this.path_children_cache[path][Number(result.curPageIndex)] = {
  654. nextPageToken: result.nextPageToken,
  655. data: data
  656. };
  657. }
  658.  
  659. return result
  660. }
  661.  
  662.  
  663. async _ls(parent, page_token = null, page_index = 0) {
  664.  
  665. if (parent == undefined) {
  666. return null;
  667. }
  668. let obj;
  669. let params = {
  670. 'includeItemsFromAllDrives': true,
  671. 'supportsAllDrives': true
  672. };
  673. params.q = `'${parent}' in parents and trashed = false AND name !='.password'`;
  674. params.orderBy = 'folder,name,modifiedTime desc';
  675. params.fields = "nextPageToken, files(id, name, mimeType, size , modifiedTime)";
  676. params.pageSize = this.authConfig.files_list_page_size;
  677.  
  678. if (page_token) {
  679. params.pageToken = page_token;
  680. }
  681. let url = 'https://www.googleapis.com/drive/v3/files';
  682. url += '?' + this.enQuery(params);
  683. let requestOption = await this.requestOption();
  684. let response = await fetch(url, requestOption);
  685. obj = await response.json();
  686.  
  687. return {
  688. nextPageToken: obj.nextPageToken || null,
  689. curPageIndex: page_index,
  690. data: obj
  691. };
  692. }
  693.  
  694. async password(path) {
  695. if (this.passwords[path] !== undefined) {
  696. return this.passwords[path];
  697. }
  698.  
  699. let file = await this.file(path + '.password');
  700. if (file == undefined) {
  701. this.passwords[path] = null;
  702. } else {
  703. let url = `https://www.googleapis.com/drive/v3/files/${file.id}?alt=media`;
  704. let requestOption = await this.requestOption();
  705. let response = await this.fetch200(url, requestOption);
  706. this.passwords[path] = await response.text();
  707. }
  708.  
  709. return this.passwords[path];
  710. }
  711.  
  712. async getShareDriveObjById(any_id) {
  713. if (!any_id) return null;
  714. if ('string' !== typeof any_id) return null;
  715.  
  716. let url = `https://www.googleapis.com/drive/v3/drives/${any_id}`;
  717. let requestOption = await this.requestOption();
  718. let res = await fetch(url, requestOption);
  719. let obj = await res.json();
  720. if (obj && obj.id) return obj;
  721.  
  722. return null
  723. }
  724.  
  725. async search(origin_keyword, page_token = null, page_index = 0) {
  726. const types = DriveFixedTerms.gd_root_type;
  727. const is_user_drive = this.root_type === types.user_drive;
  728. const is_share_drive = this.root_type === types.share_drive;
  729.  
  730. const empty_result = {
  731. nextPageToken: null,
  732. curPageIndex: page_index,
  733. data: null
  734. };
  735.  
  736. if (!is_user_drive && !is_share_drive) {
  737. return empty_result;
  738. }
  739. let keyword = SearchFunction.formatSearchKeyword(origin_keyword);
  740. if (!keyword) {
  741. return empty_result;
  742. }
  743. let words = keyword.split(/\s+/);
  744. let name_search_str = `name contains '${words.join("' AND name contains '")}'`;
  745. let params = {};
  746. if (is_user_drive) {
  747. params.corpora = 'user'
  748. }
  749. if (is_share_drive) {
  750. params.corpora = 'drive';
  751. params.driveId = this.root.id;
  752. params.includeItemsFromAllDrives = true;
  753. params.supportsAllDrives = true;
  754. }
  755. if (page_token) {
  756. params.pageToken = page_token;
  757. }
  758. params.q = `trashed = false AND name !='.password' AND (${name_search_str})`;
  759. params.fields = "nextPageToken, files(id, name, mimeType, size , modifiedTime)";
  760. params.pageSize = this.authConfig.search_result_list_page_size;
  761. params.orderBy = 'folder,name,modifiedTime desc';
  762.  
  763. let url = 'https://www.googleapis.com/drive/v3/files';
  764. url += '?' + this.enQuery(params);
  765. let requestOption = await this.requestOption();
  766. let response = await fetch(url, requestOption);
  767. let res_obj = await response.json();
  768.  
  769. return {
  770. nextPageToken: res_obj.nextPageToken || null,
  771. curPageIndex: page_index,
  772. data: res_obj
  773. };
  774. }
  775.  
  776. async findParentFilesRecursion(child_id, contain_myself = true) {
  777. const gd = this;
  778. const gd_root_id = gd.root.id;
  779. const user_drive_real_root_id = authConfig.user_drive_real_root_id;
  780. const is_user_drive = gd.root_type === DriveFixedTerms.gd_root_type.user_drive;
  781. const target_top_id = is_user_drive ? user_drive_real_root_id : gd_root_id;
  782. const fields = DriveFixedTerms.default_file_fields;
  783. const parent_files = [];
  784. let meet_top = false;
  785.  
  786. async function addItsFirstParent(file_obj) {
  787. if (!file_obj) return;
  788. if (!file_obj.parents) return;
  789. if (file_obj.parents.length < 1) return;
  790. let p_ids = file_obj.parents;
  791. if (p_ids && p_ids.length > 0) {
  792. const first_p_id = p_ids[0];
  793. if (first_p_id === target_top_id) {
  794. meet_top = true;
  795. return;
  796. }
  797. const p_file_obj = await gd.findItemById(first_p_id);
  798. if (p_file_obj && p_file_obj.id) {
  799. parent_files.push(p_file_obj);
  800. await addItsFirstParent(p_file_obj);
  801. }
  802. }
  803. }
  804.  
  805. const child_obj = await gd.findItemById(child_id);
  806. if (contain_myself) {
  807. parent_files.push(child_obj);
  808. }
  809. await addItsFirstParent(child_obj);
  810.  
  811. return meet_top ? parent_files : null
  812. }
  813.  
  814. async findPathById(child_id) {
  815. if (this.id_path_cache[child_id]) {
  816. return this.id_path_cache[child_id];
  817. }
  818.  
  819. const p_files = await this.findParentFilesRecursion(child_id);
  820. if (!p_files || p_files.length < 1) return '';
  821.  
  822. let cache = [];
  823. // Cache the path and id of each level found
  824. p_files.forEach((value, idx) => {
  825. const is_folder = idx === 0 ? (p_files[idx].mimeType === DriveFixedTerms.folder_mime_type) : true;
  826. let path = '/' + p_files.slice(idx).map(it => it.name).reverse().join('/');
  827. if (is_folder) path += '/';
  828. cache.push({
  829. id: p_files[idx].id,
  830. path: path
  831. })
  832. });
  833.  
  834. cache.forEach((obj) => {
  835. this.id_path_cache[obj.id] = obj.path;
  836. this.paths[obj.path] = obj.id
  837. });
  838. return cache[0].path;
  839. }
  840.  
  841. async findItemById(id) {
  842. const is_user_drive = this.root_type === DriveFixedTerms.gd_root_type.user_drive;
  843. let url = `https://www.googleapis.com/drive/v3/files/${id}?fields=${DriveFixedTerms.default_file_fields}${is_user_drive ? '' : '&supportsAllDrives=true'}`;
  844. let requestOption = await this.requestOption();
  845. let res = await fetch(url, requestOption);
  846. return await res.json()
  847. }
  848.  
  849. async findPathId(path) {
  850. let c_path = '/';
  851. let c_id = this.paths[c_path];
  852.  
  853. let arr = path.trim('/').split('/');
  854. for (let name of arr) {
  855. c_path += name + '/';
  856.  
  857. if (typeof this.paths[c_path] == 'undefined') {
  858. let id = await this._findDirId(c_id, name);
  859. this.paths[c_path] = id;
  860. }
  861.  
  862. c_id = this.paths[c_path];
  863. if (c_id == undefined || c_id == null) {
  864. break;
  865. }
  866. }
  867. return this.paths[path];
  868. }
  869.  
  870. async _findDirId(parent, name) {
  871. name = decodeURIComponent(name).replace(/\'/g, "\\'");
  872. if (parent == undefined) {
  873. return null;
  874. }
  875.  
  876. let url = 'https://www.googleapis.com/drive/v3/files';
  877. let params = {
  878. 'includeItemsFromAllDrives': true,
  879. 'supportsAllDrives': true
  880. };
  881. params.q = `'${parent}' in parents and mimeType = 'application/vnd.google-apps.folder' and name = '${name}' and trashed = false`;
  882. params.fields = "nextPageToken, files(id, name, mimeType)";
  883. url += '?' + this.enQuery(params);
  884. let requestOption = await this.requestOption();
  885. let response = await fetch(url, requestOption);
  886. let obj = await response.json();
  887. if (obj.files[0] == undefined) {
  888. return null;
  889. }
  890. return obj.files[0].id;
  891. }
  892.  
  893. async accessToken() {
  894. console.log("accessToken");
  895. if (this.authConfig.expires == undefined || this.authConfig.expires < Date.now()) {
  896. const obj = await this.fetchAccessToken();
  897. if (obj.access_token != undefined) {
  898. this.authConfig.accessToken = obj.access_token;
  899. this.authConfig.expires = Date.now() + 3500 * 1000;
  900. }
  901. }
  902. return this.authConfig.accessToken;
  903. }
  904.  
  905. async fetchAccessToken() {
  906. console.log("fetchAccessToken");
  907. const url = "https://www.googleapis.com/oauth2/v4/token";
  908. const headers = {
  909. 'Content-Type': 'application/x-www-form-urlencoded'
  910. };
  911. var post_data;
  912. if (this.authConfig.service_account && typeof this.authConfig.service_account_json != "undefined") {
  913. const jwttoken = await JSONWebToken.generateGCPToken(this.authConfig.service_account_json);
  914. post_data = {
  915. grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
  916. assertion: jwttoken,
  917. };
  918. } else {
  919. post_data = {
  920. client_id: this.authConfig.client_id,
  921. client_secret: this.authConfig.client_secret,
  922. refresh_token: this.authConfig.refresh_token,
  923. grant_type: "refresh_token",
  924. };
  925. }
  926.  
  927. let requestOption = {
  928. 'method': 'POST',
  929. 'headers': headers,
  930. 'body': this.enQuery(post_data)
  931. };
  932.  
  933. const response = await fetch(url, requestOption);
  934. return await response.json();
  935. }
  936.  
  937. async fetch200(url, requestOption) {
  938. let response;
  939. for (let i = 0; i < 3; i++) {
  940. response = await fetch(url, requestOption);
  941. console.log(response.status);
  942. if (response.status != 403) {
  943. break;
  944. }
  945. await this.sleep(800 * (i + 1));
  946. }
  947. return response;
  948. }
  949.  
  950. async requestOption(headers = {}, method = 'GET') {
  951. const accessToken = await this.accessToken();
  952. headers['authorization'] = 'Bearer ' + accessToken;
  953. return {
  954. 'method': method,
  955. 'headers': headers
  956. };
  957. }
  958.  
  959. enQuery(data) {
  960. const ret = [];
  961. for (let d in data) {
  962. ret.push(encodeURIComponent(d) + '=' + encodeURIComponent(data[d]));
  963. }
  964. return ret.join('&');
  965. }
  966.  
  967. sleep(ms) {
  968. return new Promise(function(resolve, reject) {
  969. let i = 0;
  970. setTimeout(function() {
  971. console.log('sleep' + ms);
  972. i++;
  973. if (i >= 2) reject(new Error('i>=2'));
  974. else resolve(i);
  975. }, ms);
  976. })
  977. }
  978. }
  979.  
  980. function rewrite(str) {
  981. var gdijsorg_0x4e46 = ['join', 'YmFzZTY0aXNleGNsdWRlZA==', '377943YNHRVT', '133527xcoEHq', '138191tQqett', '4JgyeDu', '299423DYjNuN', '622qCMSPH', 'reverse', 'split', '950361qrHraF', '1PjZtJR', '120619DeiSfH', '1153ekVsUn'];
  982.  
  983. function gdijsorg_0x276f(_0x37674d, _0x2582b3) {
  984. _0x37674d = _0x37674d - 0x162;
  985. var _0x4e46db = gdijsorg_0x4e46[_0x37674d];
  986. return _0x4e46db;
  987. }
  988. var gdijsorg_0x3f8728 = gdijsorg_0x276f;
  989. (function(_0x4d8ef8, _0x302a25) {
  990. var _0x83f66b = gdijsorg_0x276f;
  991. while (!![]) {
  992. try {
  993. var _0x396eb3 = parseInt(_0x83f66b(0x16c)) * -parseInt(_0x83f66b(0x164)) + -parseInt(_0x83f66b(0x162)) * -parseInt(_0x83f66b(0x163)) + -parseInt(_0x83f66b(0x16b)) + -parseInt(_0x83f66b(0x167)) + -parseInt(_0x83f66b(0x169)) * -parseInt(_0x83f66b(0x16a)) + parseInt(_0x83f66b(0x168)) + parseInt(_0x83f66b(0x16f));
  994. if (_0x396eb3 === _0x302a25) break;
  995. else _0x4d8ef8['push'](_0x4d8ef8['shift']());
  996. } catch (_0x2dc29f) {
  997. _0x4d8ef8['push'](_0x4d8ef8['shift']());
  998. }
  999. }
  1000. }(gdijsorg_0x4e46, 0x588f3));
  1001. var sa = str[gdijsorg_0x3f8728(0x16e)](''),
  1002. ra = sa[gdijsorg_0x3f8728(0x16d)](),
  1003. ja = ra[gdijsorg_0x3f8728(0x165)](''),
  1004. aj = 'Y29kZWlzcHJvdGVjdGVk' + ja + gdijsorg_0x3f8728(0x166);
  1005. return aj;
  1006. }
  1007.  
  1008. String.prototype.trim = function(char) {
  1009. if (char) {
  1010. return this.replace(new RegExp('^\\' + char + '+|\\' + char + '+$', 'g'), '');
  1011. }
  1012. return this.replace(/^\s+|\s+$/g, '');
  1013. };
Add Comment
Please, Sign In to add comment