please help!
Working via azure portal
not working via my code
https://y2drag.blob.core.windows.net/y2drag/irj4xgf3.png?sp=r&st=2025-05-19T21:50:50Z&se=2025-05-20T05:50:50Z&spr=https&sv=2024-11-04&sr=b&sig=hwAlXGH6g%2FHeq2s6oJEB9EHnBozKo6kb3fmNh7j63Uk%3D
what do i do wrong??
import { HTMLRewriter } from “https://raw.githubusercontent.com/worker-tools/html-rewriter/master/index.ts”;
const accountName = Deno.env.get(“REACT_APP_AZURE_ACCOUNT_NAME”)?.toLowerCase();
const containerName = Deno.env
.get(“REACT_APP_AZURE_CONTAINER_NAME”)
?.toLowerCase();
const accountKey = Deno.env.get(“REACT_APP_AZURE_ACCOUNT_KEY”);
// Utility functions
function base64ToUint8Array(base64) {
const binaryStr = atob(base64);
const bytes = new Uint8Array(binaryStr.length);
for (let i = 0; i < binaryStr.length; i++) {
bytes[i] = binaryStr.charCodeAt(i);
}
return bytes;
}
function stringToUint8Array(str) {
return new TextEncoder().encode(str);
}
function base64Encode(bytes) {
let binary = “”;
bytes.forEach((b) => (binary += String.fromCharCode(b)));
return btoa(binary);
}
async function getSignature(keyBase64, stringToSign) {
const key = base64ToUint8Array(keyBase64);
const msg = stringToUint8Array(stringToSign);
const cryptoKey = await crypto.subtle.importKey(
“raw”,
key,
{ name: “HMAC”, hash: “SHA-256” },
false,
[“sign”]
);
const sigBuffer = await crypto.subtle.sign(“HMAC”, cryptoKey, msg);
return base64Encode(new Uint8Array(sigBuffer));
}
function formatAzureTime(date) {
// Format: YYYY-MM-DDTHH:MM:SSZ (no milliseconds)
return date.toISOString().replace(/.\d{3}Z$/, “Z”);
}
async function generateBlobSasToken(
accountName,
accountKey,
containerName,
blobName
) {
const now = new Date();
// Adjust start and expiry times
const startTime = new Date(now.getTime() - 53 * 60 * 1000); // 53 minutes ago
const expiryTime = new Date(startTime.getTime() + 8 * 60 * 60 * 1000); // 8 hours later
const st = formatAzureTime(startTime);
const se = formatAzureTime(expiryTime);
const canonicalizedResource = /blob/${accountName}/${containerName}/${blobName}
;
const stringToSign = [
“r”, // signed permissions
st, // start time
se, // expiry time
canonicalizedResource,
“”, // signed identifier
“”, // signed IP
“https”, // signed protocol
“2024-11-04”, // signed version
“b”, // signed resource — this MUST be here
“”,
“”,
“”,
“”,
“”,
“”,
“”,
].join(“\n”);
const signature = await getSignature(accountKey, stringToSign);
const token = [
sp=r
,
st=${st}
,
se=${se}
,
spr=https
,
sv=2024-11-04
,
sr=b
,
sig=${encodeURIComponent(signature)}
,
].join(“&”);
return {
token,
stringToSign,
signature,
};
}
const fallbackImageUrl = “https://i.ibb.co/J35J7Jy/y2dragbanner.png”;
class MetaRewriter {
constructor(imageUrl) {
this.imageUrl = imageUrl;
this.found = false;
}
element(element) {
if (element.getAttribute(“property”) === “og:image”) {
element.setAttribute(“content”, this.imageUrl);
this.found = true;
}
}
}
class HeadRewriter {
constructor(metaRewriter, debugInfo) {
this.metaRewriter = metaRewriter;
this.debugInfo = debugInfo;
}
element(element) {
if (!this.metaRewriter.found) {
element.append(
<meta property="og:image" content="${this.metaRewriter.imageUrl}">
,
{ html: true }
);
}
element.append(\n<!-- DEBUG START -->\n
, { html: true });
element.append(<!-- ACCOUNT: ${this.debugInfo.accountName} -->\n
, {
html: true,
});
element.append(<!-- CONTAINER: ${this.debugInfo.containerName} -->\n
, {
html: true,
});
element.append(<!-- BLOB: ${this.debugInfo.blobName} -->\n
, {
html: true,
});
element.append(<!-- FULL URL: ${this.debugInfo.candidateUrl} -->\n
, {
html: true,
});
element.append(<!-- SAS TOKEN: ${this.debugInfo.sasToken} -->\n
, {
html: true,
});
element.append(
<!-- STRING TO SIGN: ${this.debugInfo.stringToSign.replace( /\n/g, "\\n" )} -->\n
,
{ html: true }
);
element.append(<!-- DEBUG END -->\n
, { html: true });
}
}
export default async (request, context) => {
const url = new URL(request.url);
const pathname = url.pathname;
const queryString = pathname.replace(/^/+/, “”);
let imageUrl = fallbackImageUrl;
let candidateUrl = null;
let sasDetails = null;
let headStatus = “not requested”;
let errorMsg = “”;
if (
accountName &&
containerName &&
accountKey &&
queryString &&
!queryString.includes(“.”)
) {
const blobName = ${queryString}.png
;
try {
sasDetails = await generateBlobSasToken(
accountName,
accountKey,
containerName,
blobName
);
candidateUrl = https://${accountName}.blob.core.windows.net/${containerName}/${encodeURIComponent( blobName )}?${sasDetails.token}
;
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
const headResponse = await fetch(candidateUrl, {
method: "HEAD",
signal: controller.signal,
});
clearTimeout(timeout);
headStatus = headResponse.status;
if (headResponse.ok) {
imageUrl = candidateUrl;
}
} catch (e) {
errorMsg = e.message || String(e);
}
}
const response = await context.next();
if (!response.headers.get(“content-type”)?.includes(“text/html”)) {
return response;
}
const debugInfo = {
accountName,
containerName,
blobName: queryString.includes(“.”) ? “invalid” : ${queryString}.png
,
candidateUrl,
sasToken: sasDetails?.token || “none”,
stringToSign: sasDetails?.stringToSign || “none”,
headStatus,
errorMsg: errorMsg || “none”,
};
const metaRewriter = new MetaRewriter(imageUrl);
return new HTMLRewriter()
.on(“meta[property=‘og:image’]”, metaRewriter)
.on(“head”, new HeadRewriter(metaRewriter, debugInfo))
.transform(response);
};
export const config = {
path: “/*”,
};