azot 0.7.0 → 0.7.2

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.
@@ -7820,24 +7820,25 @@ license.help = help2;
7820
7820
  // package.json
7821
7821
  var package_default = {
7822
7822
  name: "azot",
7823
- version: "0.7.0",
7823
+ version: "0.7.2",
7824
7824
  description: "Swiss Army knife for pentesting DRMs",
7825
7825
  type: "module",
7826
7826
  files: [
7827
7827
  "dist",
7828
7828
  "scripts"
7829
7829
  ],
7830
- main: "dist/lib.cjs",
7831
- module: "dist/lib.js",
7830
+ main: "dist/lib/main.cjs",
7831
+ module: "dist/lib/main.js",
7832
7832
  bin: {
7833
- azot: "dist/cli.js"
7833
+ azot: "dist/cli/main.cjs"
7834
7834
  },
7835
7835
  scripts: {
7836
- prepublishOnly: "npm run build:lib",
7836
+ prepublishOnly: "npm run build:lib && npm run build:cli",
7837
7837
  dev: "wxt",
7838
7838
  "dev:firefox": "wxt -b firefox",
7839
- build: "npm run build:lib && npm run build:chrome",
7840
- "build:lib": "tsup --entry.lib src/lib/main.ts --entry.cli src/cli/main.ts --format cjs,esm --shims --dts --clean",
7839
+ build: "npm run build:lib && npm run build:cli && npm run build:chrome",
7840
+ "build:lib": "tsup --config tsup.lib.config.ts",
7841
+ "build:cli": "tsup --config tsup.cli.config.ts",
7841
7842
  "build:chrome": "wxt build",
7842
7843
  "build:firefox": "wxt build -b firefox",
7843
7844
  zip: "wxt zip",
@@ -7879,12 +7880,12 @@ var package_default = {
7879
7880
  exports: {
7880
7881
  ".": {
7881
7882
  require: {
7882
- types: "./dist/lib.d.cts",
7883
- default: "./dist/lib.cjs"
7883
+ types: "./dist/lib/main.d.cts",
7884
+ default: "./dist/lib/main.cjs"
7884
7885
  },
7885
7886
  import: {
7886
- types: "./dist/lib.d.ts",
7887
- default: "./dist/lib.js"
7887
+ types: "./dist/lib/main.d.ts",
7888
+ default: "./dist/lib/main.js"
7888
7889
  }
7889
7890
  }
7890
7891
  },
@@ -7892,7 +7893,6 @@ var package_default = {
7892
7893
  node: "20 || 21 || 22 || 23"
7893
7894
  },
7894
7895
  dependencies: {
7895
- "@fastify/autoload": "^6.0.2",
7896
7896
  "@fastify/helmet": "^13.0.0",
7897
7897
  "@fastify/rate-limit": "^10.2.1",
7898
7898
  "@fastify/sensible": "^6.0.1",
@@ -7929,10 +7929,9 @@ var package_default = {
7929
7929
  };
7930
7930
 
7931
7931
  // src/cli/commands/serve/serve.ts
7932
- var import_promises5 = require("fs/promises");
7933
- var import_node_path4 = require("path");
7932
+ var import_promises6 = require("fs/promises");
7933
+ var import_node_path5 = require("path");
7934
7934
  var import_fastify = __toESM(require("fastify"), 1);
7935
- var import_autoload = __toESM(require("@fastify/autoload"), 1);
7936
7935
  var import_rate_limit = __toESM(require("@fastify/rate-limit"), 1);
7937
7936
  var import_helmet = __toESM(require("@fastify/helmet"), 1);
7938
7937
  var import_sensible = __toESM(require("@fastify/sensible"), 1);
@@ -7958,6 +7957,8 @@ var help3 = () => {
7958
7957
 
7959
7958
  // src/cli/commands/serve/state.ts
7960
7959
  var import_promises4 = require("fs/promises");
7960
+ var sessions = /* @__PURE__ */ new Map();
7961
+ var clients = /* @__PURE__ */ new Map();
7961
7962
  var defaultConfig = {
7962
7963
  host: "0.0.0.0",
7963
7964
  port: 4e3,
@@ -7971,30 +7972,216 @@ var loadConfig = async (configPath) => {
7971
7972
  Object.assign(config, data);
7972
7973
  };
7973
7974
 
7975
+ // src/cli/commands/serve/api/session.ts
7976
+ var import_promises5 = require("fs/promises");
7977
+ var import_node_path4 = require("path");
7978
+ var import_typebox = require("@sinclair/typebox");
7979
+ var plugin = async (server) => {
7980
+ server.post(
7981
+ "/session",
7982
+ {
7983
+ schema: {
7984
+ body: import_typebox.Type.Object({
7985
+ client: import_typebox.Type.String()
7986
+ }),
7987
+ response: {
7988
+ 200: import_typebox.Type.Object({
7989
+ id: import_typebox.Type.String()
7990
+ }),
7991
+ 403: import_typebox.Type.Object({
7992
+ error: import_typebox.Type.String()
7993
+ })
7994
+ }
7995
+ }
7996
+ },
7997
+ async (request, reply) => {
7998
+ const secretKey = request.headers["x-secret-key"];
7999
+ const clientName = request.body.client;
8000
+ const user = config.users[secretKey];
8001
+ const clientPath = config.clients.find(
8002
+ (client2) => (0, import_node_path4.basename)(client2).includes(clientName)
8003
+ );
8004
+ const clientAllowed = user?.clients.includes(clientName);
8005
+ if (!clientPath || !clientAllowed) {
8006
+ return reply.forbidden(
8007
+ "Client is not found or you are not authorized to use it."
8008
+ );
8009
+ }
8010
+ if (!clients.has(clientName)) {
8011
+ const wvd = await (0, import_promises5.readFile)(clientPath);
8012
+ const client2 = await Client.fromPacked(wvd);
8013
+ clients.set(clientName, client2);
8014
+ }
8015
+ const session = new Session("temporary", clients.get(clientName));
8016
+ const sessionKey = `${secretKey}:${session.sessionId}`;
8017
+ sessions.set(sessionKey, session);
8018
+ return { id: session.sessionId };
8019
+ }
8020
+ );
8021
+ server.post(
8022
+ "/session/:id/generate-request",
8023
+ {
8024
+ schema: {
8025
+ params: import_typebox.Type.Object({
8026
+ id: import_typebox.Type.String()
8027
+ }),
8028
+ body: import_typebox.Type.Object({
8029
+ initDataType: import_typebox.Type.Optional(import_typebox.Type.String()),
8030
+ initData: import_typebox.Type.String()
8031
+ }),
8032
+ response: {
8033
+ 200: import_typebox.Type.Object({
8034
+ licenseRequest: import_typebox.Type.String()
8035
+ }),
8036
+ 400: import_typebox.Type.Object({
8037
+ error: import_typebox.Type.String()
8038
+ })
8039
+ }
8040
+ }
8041
+ },
8042
+ async (request, reply) => {
8043
+ const secretKey = request.headers["x-secret-key"];
8044
+ const sessionId = request.params.id;
8045
+ const sessionKey = `${secretKey}:${sessionId}`;
8046
+ const session = sessions.get(sessionKey);
8047
+ if (!session) {
8048
+ return reply.badGateway(
8049
+ "Session not found. Unable to generate request."
8050
+ );
8051
+ }
8052
+ const initDataType = request.body.initDataType || "cenc";
8053
+ const initData = Buffer.from(request.body.initData, "base64");
8054
+ session.generateRequest(initDataType, initData);
8055
+ const data = await session.waitForLicenseRequest();
8056
+ const licenseRequest = Buffer.from(data).toString("base64");
8057
+ return reply.send({ licenseRequest });
8058
+ }
8059
+ );
8060
+ server.post(
8061
+ "/session/:id/update",
8062
+ {
8063
+ schema: {
8064
+ params: import_typebox.Type.Object({
8065
+ id: import_typebox.Type.String()
8066
+ }),
8067
+ body: import_typebox.Type.Object({
8068
+ response: import_typebox.Type.String()
8069
+ }),
8070
+ response: {
8071
+ 400: import_typebox.Type.Object({
8072
+ error: import_typebox.Type.String()
8073
+ })
8074
+ }
8075
+ }
8076
+ },
8077
+ async (request, reply) => {
8078
+ const secretKey = request.headers["x-secret-key"];
8079
+ const sessionId = request.params.id;
8080
+ const sessionKey = `${secretKey}:${sessionId}`;
8081
+ const session = sessions.get(sessionKey);
8082
+ if (!session) {
8083
+ return reply.badGateway("Session not found. Unable to update.");
8084
+ }
8085
+ const response = Buffer.from(request.body.response, "base64");
8086
+ await session.update(response);
8087
+ return reply.send();
8088
+ }
8089
+ );
8090
+ server.get(
8091
+ "/session/:id/keys",
8092
+ {
8093
+ schema: {
8094
+ params: import_typebox.Type.Object({
8095
+ id: import_typebox.Type.String()
8096
+ }),
8097
+ response: {
8098
+ 200: import_typebox.Type.Array(
8099
+ import_typebox.Type.Object({
8100
+ kid: import_typebox.Type.String(),
8101
+ key: import_typebox.Type.String(),
8102
+ type: import_typebox.Type.String()
8103
+ })
8104
+ ),
8105
+ 400: import_typebox.Type.Object({
8106
+ error: import_typebox.Type.String()
8107
+ })
8108
+ }
8109
+ }
8110
+ },
8111
+ async (request, reply) => {
8112
+ const secretKey = request.headers["x-secret-key"];
8113
+ const sessionId = request.params.id;
8114
+ const sessionKey = `${secretKey}:${sessionId}`;
8115
+ const session = sessions.get(sessionKey);
8116
+ if (!session) {
8117
+ return reply.badGateway("Session not found. Unable to get keys.");
8118
+ }
8119
+ const keys = [];
8120
+ for (const key of session.keys.values()) {
8121
+ keys.push({
8122
+ kid: key.id,
8123
+ key: key.value,
8124
+ type: key.type
8125
+ });
8126
+ }
8127
+ return reply.send(keys);
8128
+ }
8129
+ );
8130
+ server.delete(
8131
+ "/session/:id",
8132
+ {
8133
+ schema: {
8134
+ params: import_typebox.Type.Object({
8135
+ id: import_typebox.Type.String()
8136
+ }),
8137
+ response: {
8138
+ 400: import_typebox.Type.Object({
8139
+ error: import_typebox.Type.String()
8140
+ })
8141
+ }
8142
+ }
8143
+ },
8144
+ async (request, reply) => {
8145
+ const secretKey = request.headers["x-secret-key"];
8146
+ const sessionId = request.params.id;
8147
+ const sessionKey = `${secretKey}:${sessionId}`;
8148
+ const session = sessions.get(sessionKey);
8149
+ if (!session) {
8150
+ return reply.badGateway(
8151
+ "No session has been opened yet. No session to close."
8152
+ );
8153
+ }
8154
+ await session.close();
8155
+ sessions.delete(sessionKey);
8156
+ return reply.send();
8157
+ }
8158
+ );
8159
+ };
8160
+ var session_default = plugin;
8161
+
7974
8162
  // src/cli/commands/serve/serve.ts
7975
- var import_meta = {};
7976
8163
  var serve = async (options = {}) => {
7977
8164
  const server = (0, import_fastify.default)({ logger: true });
7978
8165
  const configPath = options.config || "azot.config.json";
7979
8166
  await loadConfig(configPath);
7980
8167
  if (options.client) config.clients.push(options.client);
7981
8168
  if (!config.clients.length) {
7982
- const files = await (0, import_promises5.readdir)(process.cwd());
8169
+ const files = await (0, import_promises6.readdir)(process.cwd());
7983
8170
  const clientPath = files.find((file) => file.endsWith(".wvd"));
7984
8171
  if (clientPath) config.clients.push(clientPath);
7985
8172
  }
7986
8173
  if (options.secret) {
7987
8174
  const anonymousUser = { name: "anonymous", clients: [] };
7988
8175
  const user = config.users[options.secret] || anonymousUser;
7989
- const clientFilename = (0, import_node_path4.basename)(options.client || config.clients.at(-1));
7990
- const clientName = clientFilename.replace((0, import_node_path4.extname)(clientFilename), "");
8176
+ const clientFilename = (0, import_node_path5.basename)(options.client || config.clients.at(-1));
8177
+ const clientName = clientFilename.replace((0, import_node_path5.extname)(clientFilename), "");
7991
8178
  if (!user.clients.length) user.clients.push(clientName);
7992
8179
  config.users[options.secret] = user;
7993
8180
  }
7994
- server.register(import_autoload.default, { dir: `${import_meta.dirname || __dirname}/api` });
7995
8181
  server.register(import_rate_limit.default, { max: 100, timeWindow: "1 minute" });
7996
8182
  server.register(import_helmet.default, { global: true });
7997
8183
  server.register(import_sensible.default);
8184
+ session_default(server, {});
7998
8185
  server.listen({ port: options.port || 4e3, host: options.host || "0.0.0.0" }).catch((err) => {
7999
8186
  server.log.error(err);
8000
8187
  process.exit(1);
@@ -1,10 +1,3 @@
1
- // node_modules/tsup/assets/esm_shims.js
2
- import { fileURLToPath } from "url";
3
- import path from "path";
4
- var getFilename = () => fileURLToPath(import.meta.url);
5
- var getDirname = () => path.dirname(getFilename());
6
- var __dirname = /* @__PURE__ */ getDirname();
7
-
8
1
  // src/lib/proto/license_protocol.pb.js
9
2
  import * as protobufjs from "protobufjs/minimal.js";
10
3
  var $protobuf = protobufjs.default || protobufjs;
@@ -7676,17 +7669,15 @@ var fetchDecryptionKeys = async (params) => {
7676
7669
  const keys = Array.from(session.keys.values());
7677
7670
  return keys;
7678
7671
  };
7679
-
7680
7672
  export {
7681
- __dirname,
7682
- fromText,
7683
- fromBinary,
7673
+ CLIENT_TYPE,
7674
+ Client,
7675
+ Key,
7676
+ Session,
7677
+ fetchDecryptionKeys,
7684
7678
  fromBase64,
7679
+ fromBinary,
7685
7680
  fromBuffer,
7686
7681
  fromHex,
7687
- Key,
7688
- Session,
7689
- CLIENT_TYPE,
7690
- Client,
7691
- fetchDecryptionKeys
7682
+ fromText
7692
7683
  };
package/package.json CHANGED
@@ -1,23 +1,24 @@
1
1
  {
2
2
  "name": "azot",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Swiss Army knife for pentesting DRMs",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
8
8
  "scripts"
9
9
  ],
10
- "main": "dist/lib.cjs",
11
- "module": "dist/lib.js",
10
+ "main": "dist/lib/main.cjs",
11
+ "module": "dist/lib/main.js",
12
12
  "bin": {
13
- "azot": "dist/cli.js"
13
+ "azot": "dist/cli/main.cjs"
14
14
  },
15
15
  "scripts": {
16
- "prepublishOnly": "npm run build:lib",
16
+ "prepublishOnly": "npm run build:lib && npm run build:cli",
17
17
  "dev": "wxt",
18
18
  "dev:firefox": "wxt -b firefox",
19
- "build": "npm run build:lib && npm run build:chrome",
20
- "build:lib": "tsup --entry.lib src/lib/main.ts --entry.cli src/cli/main.ts --format cjs,esm --shims --dts --clean",
19
+ "build": "npm run build:lib && npm run build:cli && npm run build:chrome",
20
+ "build:lib": "tsup --config tsup.lib.config.ts",
21
+ "build:cli": "tsup --config tsup.cli.config.ts",
21
22
  "build:chrome": "wxt build",
22
23
  "build:firefox": "wxt build -b firefox",
23
24
  "zip": "wxt zip",
@@ -59,12 +60,12 @@
59
60
  "exports": {
60
61
  ".": {
61
62
  "require": {
62
- "types": "./dist/lib.d.cts",
63
- "default": "./dist/lib.cjs"
63
+ "types": "./dist/lib/main.d.cts",
64
+ "default": "./dist/lib/main.cjs"
64
65
  },
65
66
  "import": {
66
- "types": "./dist/lib.d.ts",
67
- "default": "./dist/lib.js"
67
+ "types": "./dist/lib/main.d.ts",
68
+ "default": "./dist/lib/main.js"
68
69
  }
69
70
  }
70
71
  },
@@ -72,7 +73,6 @@
72
73
  "node": "20 || 21 || 22 || 23"
73
74
  },
74
75
  "dependencies": {
75
- "@fastify/autoload": "^6.0.2",
76
76
  "@fastify/helmet": "^13.0.0",
77
77
  "@fastify/rate-limit": "^10.2.1",
78
78
  "@fastify/sensible": "^6.0.1",
package/dist/cli.d.cts DELETED
@@ -1 +0,0 @@
1
- #!/usr/bin/env node
package/dist/cli.d.ts DELETED
@@ -1 +0,0 @@
1
- #!/usr/bin/env node
package/dist/cli.js DELETED
@@ -1,447 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- Client,
4
- __dirname,
5
- fetchDecryptionKeys
6
- } from "./chunk-4ZXWXL4G.js";
7
-
8
- // src/cli/main.ts
9
- import { parseArgs } from "node:util";
10
-
11
- // src/cli/utils.ts
12
- import { readdir, readFile, stat } from "node:fs/promises";
13
- import { join } from "node:path";
14
- var importClient = async (input) => {
15
- const inputStat = await stat(input);
16
- const isDir = inputStat.isDirectory();
17
- if (isDir) {
18
- const entries = isDir ? await readdir(input) : [];
19
- const idFilename = entries.find((entry) => entry.includes("client_id"));
20
- const keyFilename = entries.find((entry) => entry.includes("private_key"));
21
- const wvdFilename = entries.find((entry) => entry.endsWith("wvd"));
22
- const isUnpacked = !!(idFilename && keyFilename);
23
- const isPacked = !!wvdFilename;
24
- if (isUnpacked) {
25
- const idPath = join(input, idFilename);
26
- const keyPath = join(input, keyFilename);
27
- const id = await readFile(idPath);
28
- const key = await readFile(keyPath);
29
- return Client.fromUnpacked(id, key);
30
- } else if (isPacked) {
31
- const wvdPath = join(input, wvdFilename);
32
- const wvd = await readFile(wvdPath);
33
- return await Client.fromPacked(wvd);
34
- } else {
35
- console.log(`Unable to find client files in ${input}`);
36
- process.exit(1);
37
- }
38
- } else if (input.endsWith(".wvd")) {
39
- const wvd = await readFile(input);
40
- return Client.fromPacked(wvd);
41
- } else {
42
- console.log(`Unable to find client files in ${input}`);
43
- process.exit(1);
44
- }
45
- };
46
- var col = (str, offset = 2, width = 30) => `${" ".repeat(offset)}${str.padEnd(width)}`;
47
-
48
- // src/cli/commands/client/help.ts
49
- var help = () => {
50
- console.log(`azot client: Widevine client utilities
51
- `);
52
- console.log(`Usage: azot client <subcommand> [...flags]
53
- `);
54
- console.log(`Commands:`);
55
- console.log(
56
- col(`info <input>`) + "print info about client that is on <input> path (*.wvd filepath or directory with id and private key)"
57
- );
58
- console.log(
59
- col(`pack <input> <output>`) + "pack client id and private key from <input> directory into single *.wvd file with <output> path"
60
- );
61
- console.log(
62
- col(`unpack <input> <output>`) + "unpack *.wvd from <input> path to separate client id and private key placed in <output> directory"
63
- );
64
- console.log("");
65
- console.log(`Flags:`);
66
- console.log(col(`-h, --help`) + "Display this menu and exit");
67
- };
68
-
69
- // src/cli/commands/client/info.ts
70
- var info = async (input) => {
71
- const client2 = await importClient(input);
72
- for (const [key, value] of client2.info.entries()) {
73
- console.log(`${key}: ${value}`);
74
- }
75
- };
76
-
77
- // src/cli/commands/client/pack.ts
78
- import { writeFile } from "node:fs/promises";
79
- import { join as join2 } from "node:path";
80
- var pack = async (input = process.cwd(), output) => {
81
- const client2 = await importClient(input);
82
- const wvd = await client2.pack();
83
- const wvdName = `${client2.info.get("company_name")}_${client2.info.get("model_name")}`;
84
- const wvdOutput = output || join2(process.cwd(), `${wvdName}.wvd`);
85
- await writeFile(wvdOutput, wvd);
86
- console.log(`Client packed: ${wvdOutput}`);
87
- };
88
-
89
- // src/cli/commands/client/unpack.ts
90
- import { writeFile as writeFile2 } from "node:fs/promises";
91
- import { join as join3 } from "node:path";
92
- var unpack = async (input = process.cwd(), output) => {
93
- const client2 = await importClient(input);
94
- const [id, key] = await client2.unpack();
95
- const idOutput = join3(output || process.cwd(), `device_client_id_blob`);
96
- const keyOutput = join3(output || process.cwd(), `device_private_key`);
97
- await writeFile2(idOutput, id);
98
- await writeFile2(keyOutput, key);
99
- console.log(`Client unpacked: ${idOutput}, ${keyOutput}`);
100
- };
101
-
102
- // src/cli/commands/client/index.ts
103
- var client = { info, pack, unpack, help };
104
-
105
- // src/cli/commands/license/help.ts
106
- var help2 = () => {
107
- console.log(`azot license: Make license request
108
- `);
109
- console.log(`Usage: azot license <url> [...flags]
110
- `);
111
- console.log(`Commands:`);
112
- console.log(
113
- col(`<url>`) + "URL of license server (e.g. https://cwip-shaka-proxy.appspot.com/no_auth)"
114
- );
115
- console.log("");
116
- console.log(`Flags:`);
117
- console.log(
118
- col(`-H, --header`) + 'headers to send with license request, compatible with curl (e.g. -H "Authorization: Bearer ...")'
119
- );
120
- console.log(col(`-p, --pssh`) + "widevine PSSH data in Base64");
121
- console.log(
122
- col(`-c, --client`) + "path to client (directory with id and private key or path to *.wvd file)"
123
- );
124
- console.log(
125
- col(`-e, --encrypt`) + "enable client encryption with service certificate, disabled by default"
126
- );
127
- console.log(col(`-h, --help`) + "display this menu and exit");
128
- };
129
-
130
- // src/cli/commands/license/license.ts
131
- var license = async (params) => {
132
- const headers = Object.fromEntries(
133
- params.headers?.map((header) => header.split(":").map((s) => s.trim())) || []
134
- );
135
- const keys = await fetchDecryptionKeys({
136
- server: params.url,
137
- pssh: params.pssh,
138
- client: await importClient(params.clientPath || process.cwd()),
139
- headers
140
- });
141
- for (const key of keys) {
142
- console.log(`${key.id}:${key.value}`);
143
- }
144
- return keys;
145
- };
146
- license.help = help2;
147
-
148
- // package.json
149
- var package_default = {
150
- name: "azot",
151
- version: "0.7.0",
152
- description: "Swiss Army knife for pentesting DRMs",
153
- type: "module",
154
- files: [
155
- "dist",
156
- "scripts"
157
- ],
158
- main: "dist/lib.cjs",
159
- module: "dist/lib.js",
160
- bin: {
161
- azot: "dist/cli.js"
162
- },
163
- scripts: {
164
- prepublishOnly: "npm run build:lib",
165
- dev: "wxt",
166
- "dev:firefox": "wxt -b firefox",
167
- build: "npm run build:lib && npm run build:chrome",
168
- "build:lib": "tsup --entry.lib src/lib/main.ts --entry.cli src/cli/main.ts --format cjs,esm --shims --dts --clean",
169
- "build:chrome": "wxt build",
170
- "build:firefox": "wxt build -b firefox",
171
- zip: "wxt zip",
172
- "zip:firefox": "wxt zip -b firefox",
173
- compile: "tsc --noEmit",
174
- postinstall: "node scripts/postinstall.js",
175
- test: "vitest"
176
- },
177
- repository: {
178
- type: "git",
179
- url: "https://github.com/vitalygashkov/azot"
180
- },
181
- keywords: [
182
- "widevine",
183
- "drm",
184
- "google",
185
- "pssh",
186
- "eme",
187
- "encrypted-media-extensions",
188
- "media"
189
- ],
190
- author: "Vitaly Gashkov <vitalygashkov@vk.com>",
191
- license: "AGPL-3.0",
192
- readmeFilename: "README.md",
193
- bugs: {
194
- url: "https://github.com/vitalygashkov/azot/issues",
195
- email: "vitalygashkov@vk.com"
196
- },
197
- funding: [
198
- {
199
- type: "individual",
200
- url: "https://boosty.to/vitalygashkov"
201
- },
202
- {
203
- type: "patreon",
204
- url: "https://www.patreon.com/vitalygashkov"
205
- }
206
- ],
207
- exports: {
208
- ".": {
209
- require: {
210
- types: "./dist/lib.d.cts",
211
- default: "./dist/lib.cjs"
212
- },
213
- import: {
214
- types: "./dist/lib.d.ts",
215
- default: "./dist/lib.js"
216
- }
217
- }
218
- },
219
- engines: {
220
- node: "20 || 21 || 22 || 23"
221
- },
222
- dependencies: {
223
- "@fastify/autoload": "^6.0.2",
224
- "@fastify/helmet": "^13.0.0",
225
- "@fastify/rate-limit": "^10.2.1",
226
- "@fastify/sensible": "^6.0.1",
227
- "@fastify/type-provider-typebox": "^5.1.0",
228
- "@sinclair/typebox": "^0.34.11",
229
- fastify: "^5.1.0",
230
- jsrsasign: "^11.1.0",
231
- protobufjs: "^7.4.0"
232
- },
233
- devDependencies: {
234
- "@eslint/js": "^9.12.0",
235
- "@solidjs/router": "^0.14.10",
236
- "@types/jsrsasign": "^10.5.14",
237
- "@types/node": "^22.7.5",
238
- "@wxt-dev/module-solid": "^1.1.2",
239
- autoprefixer: "^10.4.17",
240
- clsx: "^2.1.1",
241
- eslint: "^9.12.0",
242
- "eslint-config-prettier": "^9.1.0",
243
- "eslint-plugin-prettier": "^5.2.1",
244
- globals: "^15.11.0",
245
- postcss: "^8.4.33",
246
- "solid-icons": "^1.1.0",
247
- "solid-js": "^1.9.1",
248
- "tailwind-merge": "^2.5.4",
249
- tailwindcss: "^3.4.1",
250
- tsup: "^8.3.0",
251
- typescript: "^5.6.2",
252
- "typescript-eslint": "^8.9.0",
253
- "vite-plugin-arraybuffer": "^0.0.8",
254
- vitest: "^2.1.3",
255
- wxt: "^0.19.11"
256
- }
257
- };
258
-
259
- // src/cli/commands/serve/serve.ts
260
- import { readdir as readdir2 } from "node:fs/promises";
261
- import { basename, extname } from "node:path";
262
- import fastify from "fastify";
263
- import AutoLoad from "@fastify/autoload";
264
- import RateLimit from "@fastify/rate-limit";
265
- import Helmet from "@fastify/helmet";
266
- import Sensible from "@fastify/sensible";
267
-
268
- // src/cli/commands/serve/help.ts
269
- var help3 = () => {
270
- console.log(`azot serve: Run your API instance
271
- `);
272
- console.log(`Usage: azot serve [...flags]
273
- `);
274
- console.log(`Flags:`);
275
- console.log(col(`--host`) + "server host (default: 0.0.0.0)");
276
- console.log(col(`--port`) + "server port (default: 4000)");
277
- console.log(
278
- col(`--config`) + "path to config file (default: azot.config.json)"
279
- );
280
- console.log(
281
- col(`-c, --client`) + "path to client (directory with id and private key or path to *.wvd file)"
282
- );
283
- console.log(col(`-s, --secret`) + "secret key to access API endpoints");
284
- console.log(col(`-h, --help`) + "display this menu and exit");
285
- };
286
-
287
- // src/cli/commands/serve/state.ts
288
- import { readFile as readFile2 } from "node:fs/promises";
289
- var defaultConfig = {
290
- host: "0.0.0.0",
291
- port: 4e3,
292
- clients: [],
293
- users: {},
294
- forcePrivacyMode: true
295
- };
296
- var config = defaultConfig;
297
- var loadConfig = async (configPath) => {
298
- const data = await readFile2(configPath, { encoding: "utf-8" }).then((data2) => JSON.parse(data2)).catch(() => defaultConfig);
299
- Object.assign(config, data);
300
- };
301
-
302
- // src/cli/commands/serve/serve.ts
303
- var serve = async (options = {}) => {
304
- const server = fastify({ logger: true });
305
- const configPath = options.config || "azot.config.json";
306
- await loadConfig(configPath);
307
- if (options.client) config.clients.push(options.client);
308
- if (!config.clients.length) {
309
- const files = await readdir2(process.cwd());
310
- const clientPath = files.find((file) => file.endsWith(".wvd"));
311
- if (clientPath) config.clients.push(clientPath);
312
- }
313
- if (options.secret) {
314
- const anonymousUser = { name: "anonymous", clients: [] };
315
- const user = config.users[options.secret] || anonymousUser;
316
- const clientFilename = basename(options.client || config.clients.at(-1));
317
- const clientName = clientFilename.replace(extname(clientFilename), "");
318
- if (!user.clients.length) user.clients.push(clientName);
319
- config.users[options.secret] = user;
320
- }
321
- server.register(AutoLoad, { dir: `${import.meta.dirname || __dirname}/api` });
322
- server.register(RateLimit, { max: 100, timeWindow: "1 minute" });
323
- server.register(Helmet, { global: true });
324
- server.register(Sensible);
325
- server.listen({ port: options.port || 4e3, host: options.host || "0.0.0.0" }).catch((err) => {
326
- server.log.error(err);
327
- process.exit(1);
328
- });
329
- };
330
- serve.help = help3;
331
-
332
- // src/cli/main.ts
333
- var args = parseArgs({
334
- args: process.argv.slice(2),
335
- options: {
336
- pssh: { type: "string", short: "p" },
337
- client: { type: "string", short: "c" },
338
- encrypt: { type: "boolean", short: "e", default: false },
339
- header: { type: "string", short: "H", multiple: true },
340
- help: { type: "boolean", short: "h" },
341
- version: { type: "boolean", short: "v" },
342
- debug: { type: "boolean", short: "d" },
343
- host: { type: "string" },
344
- port: { type: "string" },
345
- secret: { type: "string", short: "s" },
346
- config: { type: "string" }
347
- },
348
- strict: false,
349
- allowPositionals: true
350
- });
351
- var help4 = () => {
352
- console.log(
353
- `Azot is a research & pentesting toolkit for Google's Widevine DRM. (${package_default.version})
354
- `
355
- );
356
- console.log(`Usage: azot <command> [...flags]
357
- `);
358
- console.log(`Commands:`);
359
- console.log(col(`serve`) + "Run your API instance");
360
- console.log(col(`license <url>`) + "Make a license request");
361
- console.log(
362
- col(`client <subcommand>`) + "Additional Widevine client utilities"
363
- );
364
- console.log("");
365
- console.log(`Flags:`);
366
- console.log(col(`-d, --debug`) + "Enable debug level logging");
367
- console.log(col(`-v, --version`) + "Print version and exit");
368
- console.log(col(`-h, --help`) + "Display this menu and exit");
369
- console.log("");
370
- console.log(`(more flags in azot license --help and azot client --help)`);
371
- };
372
- (async () => {
373
- if (args.values.version) {
374
- console.log(package_default.version);
375
- process.exit(0);
376
- }
377
- const [command, ...positionals] = args.positionals;
378
- switch (command) {
379
- case "serve": {
380
- if (args.values.help) {
381
- serve.help();
382
- process.exit(0);
383
- }
384
- serve({
385
- host: args.values.host,
386
- port: args.values.port ? parseInt(args.values.port) : void 0,
387
- config: args.values.config,
388
- client: args.values.client,
389
- secret: args.values.secret
390
- });
391
- break;
392
- }
393
- case "client": {
394
- const subcommand = positionals.shift();
395
- const [input, output] = positionals;
396
- switch (subcommand) {
397
- case "pack":
398
- client.pack(input, output);
399
- break;
400
- case "unpack":
401
- client.unpack(input, output);
402
- break;
403
- case "info":
404
- client.info(input);
405
- break;
406
- default: {
407
- if (args.values.help) {
408
- client.help();
409
- process.exit(0);
410
- } else {
411
- console.log("Client subcommand required: pack, unpack, info");
412
- process.exit(1);
413
- }
414
- }
415
- }
416
- break;
417
- }
418
- case "license": {
419
- if (args.values.help) {
420
- license.help();
421
- process.exit(0);
422
- }
423
- const url = positionals.shift();
424
- if (!url) throw new Error("License URL required");
425
- const pssh = args.values.pssh;
426
- if (!pssh) throw new Error("PSSH required");
427
- const clientPath = args.values.client;
428
- const encrypt = args.values.encrypt;
429
- const headers = args.values.header;
430
- await license({ url, pssh, clientPath, encrypt, headers });
431
- break;
432
- }
433
- case "pssh":
434
- break;
435
- case "test":
436
- break;
437
- default: {
438
- if (args.values.help) {
439
- help4();
440
- process.exit(0);
441
- } else {
442
- console.log("Command not found");
443
- process.exit(1);
444
- }
445
- }
446
- }
447
- })();
package/dist/lib.js DELETED
@@ -1,24 +0,0 @@
1
- import {
2
- CLIENT_TYPE,
3
- Client,
4
- Key,
5
- Session,
6
- fetchDecryptionKeys,
7
- fromBase64,
8
- fromBinary,
9
- fromBuffer,
10
- fromHex,
11
- fromText
12
- } from "./chunk-4ZXWXL4G.js";
13
- export {
14
- CLIENT_TYPE,
15
- Client,
16
- Key,
17
- Session,
18
- fetchDecryptionKeys,
19
- fromBase64,
20
- fromBinary,
21
- fromBuffer,
22
- fromHex,
23
- fromText
24
- };
File without changes
File without changes
File without changes