App feito com electron e Next para controlar camera ptz usando a api do DVR/NVR para ajudar minha congregação de lingua de sinais durante as reuniões.
- @saulotarsobc
- Intelbras
- HTTP_API_V3.35_Intelbras
- URL RTSP - Intelbras Forum
- API - Dispositivos de Controle de Acesso Corporativo - Autenticação
import crypto from "node:crypto";
export async function fetchWithDigestAuth(
url: string,
username: string,
password: string
) {
const authHeader = (
method: any,
uri: any,
nonce: any,
realm: any,
qop: any,
nc: any,
cnonce: any,
response: any
) => {
return `Digest username="${username}", realm="${realm}", nonce="${nonce}", uri="${uri}", qop=${qop}, nc=${nc}, cnonce="${cnonce}", response="${response}"`;
};
const makeDigestResponse = (
nonce: any,
realm: any,
qop: any,
method: any,
uri: any,
nc: any,
cnonce: any
) => {
const ha1 = md5(`${username}:${realm}:${password}`);
const ha2 = md5(`${method}:${uri}`);
return md5(`${ha1}:${nonce}:${nc}:${cnonce}:${qop}:${ha2}`);
};
const md5 = (str: string) => {
// Replace this with an actual MD5 implementation or import from a library
return crypto.createHash("md5").update(str).digest("hex");
};
// First request to get the WWW-Authenticate header
const initialResponse = await fetch(url);
if (!initialResponse.headers.has("www-authenticate")) {
throw new Error("No www-authenticate header in the response");
}
const authHeaderStr: any = initialResponse.headers.get("www-authenticate");
const authParams = authHeaderStr
.substring(7)
.split(", ")
.reduce((acc: any, current: any) => {
const [key, value] = current.split("=");
acc[key] = value.replace(/"/g, "");
return acc;
}, {});
const method = "GET";
const uri = url.replace(/^.*\/\/[^\/]+/, ""); // Extract URI from the URL
const nonce = authParams["nonce"];
const realm = authParams["realm"];
const qop = "auth";
const nc = "00000001";
const cnonce = Math.random().toString(36).substring(2, 15);
const responseHash = makeDigestResponse(
nonce,
realm,
qop,
method,
uri,
nc,
cnonce
);
const authorization = authHeader(
method,
uri,
nonce,
realm,
qop,
nc,
cnonce,
responseHash
);
// Second request with the Digest authorization header
const finalResponse = await fetch(url, {
headers: {
Authorization: authorization,
},
});
if (!finalResponse.ok) {
throw new Error(`HTTP error! status: ${finalResponse.status}`);
}
const buffer = await finalResponse.arrayBuffer();
const base64String = btoa(String.fromCharCode(...new Uint8Array(buffer)));
return "ok";
}
npx expo install expo-crypto;
import * as Crypto from "expo-crypto";
const md5 = async (str: string) => {
return await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.MD5, str);
};
export async function fetchWithDigestAuth(
url: string,
username: string,
password: string
) {
const authHeader = (
method: any,
uri: any,
nonce: any,
realm: any,
qop: any,
nc: any,
cnonce: any,
response: any
) => {
return `Digest username="${username}", realm="${realm}", nonce="${nonce}", uri="${uri}", qop=${qop}, nc=${nc}, cnonce="${cnonce}", response="${response}"`;
};
const makeDigestResponse = async (
nonce: any,
realm: any,
qop: any,
method: any,
uri: any,
nc: any,
cnonce: any
) => {
const ha1 = await md5(`${username}:${realm}:${password}`);
const ha2 = await md5(`${method}:${uri}`);
return await md5(`${ha1}:${nonce}:${nc}:${cnonce}:${qop}:${ha2}`);
};
// Primeira solicitação para obter o cabeçalho WWW-Authenticate
const initialResponse = await fetch(url);
if (!initialResponse.headers.has("www-authenticate")) {
throw new Error("No www-authenticate header in the response");
}
const authHeaderStr: any = initialResponse.headers.get("www-authenticate");
const authParams = authHeaderStr
.substring(7)
.split(", ")
.reduce((acc: any, current: any) => {
const [key, value] = current.split("=");
acc[key] = value.replace(/"/g, "");
return acc;
}, {});
const method = "GET";
const uri = url.replace(/^.*\/\/[^\/]+/, ""); // Extrai o URI do URL
const nonce = authParams["nonce"];
const realm = authParams["realm"];
const qop = "auth";
const nc = "00000001";
const cnonce = Math.random().toString(36).substring(2, 15);
const responseHash = await makeDigestResponse(
nonce,
realm,
qop,
method,
uri,
nc,
cnonce
);
const authorization = authHeader(
method,
uri,
nonce,
realm,
qop,
nc,
cnonce,
responseHash
);
const finalResponse = await fetch(url, {
headers: {
Authorization: authorization,
},
});
if (!finalResponse.ok) {
throw new Error(`HTTP error! status: ${finalResponse.status}`);
}
const buffer = await finalResponse.arrayBuffer();
const base64String = btoa(String.fromCharCode(...new Uint8Array(buffer)));
return base64String;
}