diff --git a/.npmignore b/.npmignore index 68f167c..66300d2 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1 @@ -.github/* -src/* \ No newline at end of file +.github/* \ No newline at end of file diff --git a/package.json b/package.json index cff6ed0..a1c5fcc 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "license": "MIT", "private": false, "dependencies": { - "@mithron/deezer-music-metadata": "^1.0.3" + "@mithron/deezer-music-metadata": "^1.0.3", + "blowfish-node": "^1.1.4" }, "devDependencies": { "@discord-player/extractor": "^4.5.1", @@ -21,7 +22,8 @@ "scripts": { "build": "yarn lint && tsup", "lint": "tslint -p tsconfig.json", - "npm:publish": "yarn build && npm publish --access public" + "npm:publish": "yarn build && npm publish --access public", + "prepare": "tsup" }, "repository": { "type": "git", diff --git a/src/DeezerExtractor.ts b/src/DeezerExtractor.ts index 4051e0b..3f67e6f 100644 --- a/src/DeezerExtractor.ts +++ b/src/DeezerExtractor.ts @@ -1,6 +1,6 @@ import { BaseExtractor, ExtractorSearchContext, ExtractorStreamable, Track, Playlist, Util as DPUtil, ExtractorInfo } from "discord-player" import { Playlist as DeezerPlaylist, Track as DeezerTrack, getData } from "@mithron/deezer-music-metadata"; -import { buildTrackFromSearch, getCrypto, searchOneTrack, streamTrack, validate } from "./utils/util"; +import { buildTrackFromSearch, deezerRegex, getCrypto, searchOneTrack, streamTrack, validate } from "./utils/util"; /** * -------------------------------NOTICE------------------------------------- @@ -23,12 +23,17 @@ export type DeezerUserInfo = { mediaUrl: string; } +export const Warnings = { + MissingDecryption: "Decryption Key missing! This is needed for extracting streams." +} as const +export type Warnings = (typeof Warnings)[keyof typeof Warnings] + export class DeezerExtractor extends BaseExtractor { static identifier: string = "com.retrouser955.discord-player.deezr-ext" userInfo!: DeezerUserInfo async activate(): Promise { - if(!this.options.decryptionKey) process.emitWarning("Decryption Key missing! This is needed for extracting streams.") + if(!this.options.decryptionKey) process.emitWarning(Warnings.MissingDecryption) else { // extract deezer username // dynamically load crypto because some might not want streaming @@ -81,6 +86,10 @@ export class DeezerExtractor extends BaseExtractor { } async handle(query: string, context: ExtractorSearchContext): Promise { + if (deezerRegex.share.test(query)) { + const redirect = await fetch(query); + query = redirect.url; // follow the redirect of deezer page links + } const metadata = await getData(query) if(metadata?.type === "song") return this.createResponse(null, [this.buildTrack(metadata, context)]) diff --git a/src/utils/util.ts b/src/utils/util.ts index 53f4d2c..0541e9a 100644 --- a/src/utils/util.ts +++ b/src/utils/util.ts @@ -2,6 +2,7 @@ import { type Player, Track, Util } from "discord-player"; import type { DeezerExtractor } from "../DeezerExtractor"; import { Readable, PassThrough } from 'stream' import type { BinaryLike, CipherGCMTypes, CipherKey, Decipher } from "crypto"; +import Blowfish from "blowfish-node"; const IV = Buffer.from(Array.from({ length: 8 }, (_, x) => x)) @@ -158,20 +159,16 @@ export async function streamTrack(track: Track, ext: DeezerExtractor) { } else { buffer = Buffer.concat([buffer, chunk]) } + + const blowfishDecrypter = new Blowfish(new Uint8Array(trackKey), Blowfish.MODE.CBC, Blowfish.PADDING.NULL) + blowfishDecrypter.setIv(new Uint8Array(IV)) while (buffer.length >= bufferSize) { const bufferSized = buffer.subarray(0, bufferSize) if (i % 3 === 0) { - const decipher = crypto.createDecipheriv( - 'bf-cbc' as unknown as CipherGCMTypes, - trackKey as unknown as CipherKey, - IV as unknown as BinaryLike - ).setAutoPadding(false) as unknown as Decipher - - // @ts-ignore - passThrough.write(decipher.update(bufferSized as unknown as ArrayBufferView)) - passThrough.write(decipher.final()) + const decipher = Buffer.from(blowfishDecrypter.decode(new Uint8Array(bufferSized), Blowfish.TYPE.UINT8_ARRAY)) + passThrough.write(decipher) } else { passThrough.write(bufferSized) } diff --git a/yarn.lock b/yarn.lock index 7be19fd..7869e67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -417,6 +417,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +blowfish-node@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/blowfish-node/-/blowfish-node-1.1.4.tgz#37bfe62a08f6d6026407399ad214c44d5bb4e01f" + integrity sha512-Iahpxc/cutT0M0tgwV5goklB+EzDuiYLgwJg050AmUG2jSIOpViWMLdnRgBxzZuNfswAgHSUiIdvmNdgL2v6DA== + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"