Incompatible PGP keys between openpgp.js and pgpy: Error “14 is not a valid HashAlgorithm”

I’m facing an issue when trying to use PGP keys generated by openpgpjs with pgpy in Python. Specifically, I am encountering the following error:

14 is not a valid HashAlgorithm

Here is my openpgpjs key generation :

const fs = require('fs');
const openpgp = require('openpgp');

// Function to generate PGP keys and save them to files
async function generateAndWritePGPKeys() {
    // Generate PGP keys
    const { privateKey, publicKey } = await openpgp.generateKey({
        type: 'rsa',
        rsaBits: 4096,
        userIDs: [{ name: 'John Doe', email: '[email protected]' }],
        passphrase: 'SuperSecurePassphrase123!',
        format: 'armored'

    });

    // Define paths for the files
    const privateKeyPath = './priv1.pgp';
    const publicKeyPath = './pub1.pgp';

    // Write the keys to files
    fs.writeFileSync(privateKeyPath, privateKey.replace(/r/g, ''));
    fs.writeFileSync(publicKeyPath, publicKey.replace(/r/g, ''));

    console.log('PGP Keys have been written to files:');
    console.log(`Private Key: ${privateKeyPath}`);
    console.log(`Public Key: ${publicKeyPath}`);
}

// Run the function to generate and write keys
generateAndWritePGPKeys();

Here is my python code :

def loadkey(key_path):
    try:
        key, _ = PGPKey.from_file(key_path)
    except Exception as e:
        print(str(e))
        return None
    return key

options.providers is not iterable

I have recently started working on my next project and am adding google authentication but receiving error at GET /api/auth/providers .

api/auth/[…nextauth]/route.js

import GoogleProvider from "next-auth/providers/google";
import { MongoDBAdapter } from "@auth/mongodb-adapter"
import client from "@/libs/mongoClient";

export const authOptions = {
    providers : [
        GoogleProvider({
            clientId: process.env.GOOGLE_CLIENT_ID,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET
        })
    ],
    adapter: MongoDBAdapter(client),
    secret: process.env.NEXTAUTH_SECRET,
};

const handler = NextAuth({authOptions})

export { handler as GET, handler as POST }

It would be great if i could have some help in solving this error

In the timeline context, universalTransition and multiple timelines don’t work

I have a code that has two problems:

(1) universalTransition doesn’t work in the timeline context.

In each data property I have configured the groupId to work with its corresponding graph, but the transition does not occur in the context of timeline. Outside of timeline, the transition occurs normally.

(2) timeline: [{...}, {...}] doesn’t seem to work (only the first object has an effect, as if there were an interference).

I set up the timeline with this format:

timeline: [
    {...},
    {...}
]

But this creates a problem, because the second timeline has no effect, even when you change the axisType, for example.

Full code:

HTML

  const chartUse = echarts.init(document.getElementsByClassName("chart")[0]);

  function chartFrameSwitch0() {
  
    const stuckSeries = [
      {
        type: "gauge",
        radius: "60%",
        center: ["25%", "70%"],
        data: [{ value: 50, groupId: "group1" }, {value: 80, groupId: "group2" }],
        universalTransition: true,
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut"
      },
      {
        type: "gauge",
        radius: "60%",
        center: ["75%", "70%"],
        data: [{ value: 30, groupId: "group3" }, { value: 90, groupId: "group4" }],
        universalTransition: true,
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut"
      },
    ]

    const baseOption0 = {
    
        timeline: [
          {
            axisType: "category",
            autoPlay: true,
            playInterval: 1500,
            data: ["2020", "2021", "2022"],
            top: "35%",
            left: "5%",
            width: "40%",
            height: "10%"
          },
          {
            axisType: "value",
            autoPlay: false,
            playInterval: 1500,
            data: [10, 20, 30],
            top: "35%",
            right: "5%",
            width: "40%",
            height: "10%"
          },
        ],
        tooltip: {},
        legend: {},
        grid: [
          {
            width: "40%",
            height: "30%",
            left: "5%",
            top: "5%",
            containLabel: true,
          },
          {
            width: "40%",
            height: "30%",
            right: "5%",
            top: "5%",
            containLabel: true,
          },
        ],
        xAxis: [
          {
            type: "category",
            gridIndex: 0,
            data: ["Product A", "Product B", "Product C"],
          },
          {
            type: "category",
            gridIndex: 1,
            data: ["Service A", "Service B", "Service C"],
          },
        ],
        yAxis: [
          { type: "value", gridIndex: 0 },
          { type: "value", gridIndex: 1 },
        ],
      },
      options0 = [
        {
          series: [
            {
              type: "line",
              name: "Vendas",
              xAxisIndex: 0,
              yAxisIndex: 0,
              data: [120, 200, 150]
            },

            {
              type: "line",
              name: "Vendas",
              xAxisIndex: 1,
              yAxisIndex: 1,
              data: [80, 180, 220],
            },
            ...stuckSeries
          ],
        },
        {
          series: [
            {
              type: "line",
              name: "Vendas",
              xAxisIndex: 0,
              yAxisIndex: 0,
              data: [180, 250, 190],
            },
            { 
              type: "line", 
              name: "Vendas", 
              xAxisIndex: 1,
              yAxisIndex: 1, 
              data: [50, 250, 110]
            },
          ],
        },
        {
          series: [
            {
              type: "line",
              name: "Vendas",
              xAxisIndex: 0,
              yAxisIndex: 0,
              data: [220, 300, 210],
            },
            { 
              type: "line", 
              name: "Vendas", 
              xAxisIndex: 1,
              yAxisIndex: 1, 
              data: [220, 300, 210] 
            }
          ]
        }
      ]

    const option = {
      baseOption: baseOption0,
      options: options0
    }

    chartUse.setOption(option);
  }

  chartFrameSwitch0();
  
  function chartFrameSwitch1 () {
    const series0 = [
      {
        type: "pie",
        center: ["25%", "70%"],
        radius: "60%",
        universalTransition: true,
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        data: [
          {
            name: "Test 1",
            value: 80,
            groupId: "group1"
          },
          {
            name: "Test 2",
            value: 90,
            groupId: "group2"
          }
        ]
      },
      {
        type: "pie",
        center: ["75%", "70%"],
        radius: "60%",
        universalTransition: true,
        animationDurationUpdate: 1000,
        animationEasingUpdate: "quinticInOut",
        data: [
          {
            name: "Test 3",
            value: 130,
            groupId: "group3"
          },
          {
            name: "Test 4",
            value: 190,
            groupId: "group4"
          }
        ]
      }
    ];
    
    const option = {
      series: series0
    };
    
    chartUse.setOption(option, {replaceMerge: ["timeline", "series", "xAxis", "yAxis"]} );
    
  }
  
  const gaugeClick = document.getElementsByClassName("gaugeBttn")[0];
  gaugeClick.addEventListener("click", chartFrameSwitch0);
  
    const pieClick = document.getElementsByClassName("pieBttn")[0];
  pieClick.addEventListener("click", chartFrameSwitch1);
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.6.0/echarts.min.js"></script>
</head>

<button class="gaugeBttn">
Gauge
</button>

<button class="pieBttn">
Pie
</button>

<div class="chart" style="width: 100%; height: 100vh"></div>

I could solve this by using several instances, but I only want to keep one: chartUse.

How to sanitize MUI autocomplete input? It doesn’t update on keypress

What I have

I have a MUI Autocomplete component inside React.

Goal

I would like to sanitize the input typed into it so the user can’t enter characters that wouldn’t make sense anyway.

What I tried

I created a native and an <Autocomplete> input too. I passed the controlled value for both the element and the input under it.

const Form = () => {
  const sanitize = value => value.replace(/[^0-9:]/g, '')
  const [value, setValue] = useState('')

  return (
    <>
      <input type="text" value={value} onChange={(e) => { setValue(sanitize(e.target.value)) }} />
      <Autocomplete
        options={['12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']}
        value={value}
        inputValue={value}
        onChange={(_, value) => { setValue(sanitize(value || '')) }}
        freeSolo
        renderInput={(params) => (
          <TextField {...params} label="Value" value={value} onChange={(e) => {
            setValue(sanitize(e.target.value))
          }} />
        )}
      />
    </>
  )
}

Problem

The native one works, so it isn’t the update logic messing up things. The MUI one is acting weird: typing in letters doesn’t get filtered out, but when I type a number after them the letters disappear.

Why React.js array which is a useState hook is not updating it’s values [duplicate]

While implementing pagination I’ve come across a problem with displaying numbers for navigation between chunks of data displayed.
This is how I tried to implement it.
I have const [displayRequestNavigationNumbers, setDisplayRequestNavigationNumbers] = useState([]); which I’m using for displaying current page, prev page and the next page, so it’s always going to be array of 3 numbers.
Also I have a function for incrementing every array item’s value by +1(when clicked on navigate next button).

  const handlePageInc = () => {
    setCurrentPage((prevPage) => {
      return prevPage + 1;
    });
  };

  const handleNavigateNext = () => {
    /* handlePageInc(); */
    console.log("TEST currentPage: ", currentPage);
    if(currentPage <= totalPages) {
      setDisplayRequestNavigationNumbers((prevValues) => {
        return prevValues.map((pageNum) => pageNum + 1);
      });
      console.log("displayRequestNavigationNumbers: ", displayRequestNavigationNumbers);
    }
  };

Since I want to disable button for navigate next when it hits the total pages I added the if statement and before the statement I’m trying to increase the current page so it makes sense.
What happens is after I uncomment the function call /* handlePageInc(); */ – the displayRequestNavigationNumbers doesn’t change and I don’t know why.

But when I do leave it commented out I get the changes I want in displayRequestNavigationNumbers but now currentPage never increases so user can keep hitting the next button which is not something I want.

I’m sharing the whole code below:

const Requests = () => {
  const [requests, setRequests] = useState([]);
  const [url, setUrl] = useState(`http://localhost:8080/requests`);
  const [requestDetails, setRequestDetails] = useState(null);
  const [isRequestModalOpen, setIsRequestModalOpen] = useState(false); 
  const [isStatusDropdownOpen, setIsStatusDropdownOpen] = useState(false);
  const [isTimeRangeDropdownOpen, setIsTimeRangeDropdownOpen] = useState(false);
  
  const [status, setStatus] = useState("ALL");
  const [sortField, setSortField] = useState("");
  const [sortDirection, setSortDirection] = useState("asc");
  const [timeRange, setTimeRange] = useState("All");
  const [totalPages, setTotalPages] = useState();
  const [currentPage, setCurrentPage] = useState(1);
  const [displayRequestNavigationNumbers, setDisplayRequestNavigationNumbers] = useState([]);


  const timeRangeList = [
    "Today",
    "Last 7 days",
    "Last month",
    "Last year",
    "All",
  ];

  const statusList = [
    "PENDING",
    "APPROVED",
    "DECLINED",
    "ALL"
  ];

  const getRquests = async () => {
    const fetchedRequests = await axios.get(url + `?status=${status}&sortField=${sortField}&sortDirection=${sortDirection}&timeRange=${timeRange}&pageNumber=${currentPage}`);
    setTotalPages(fetchedRequests.data.totalPages);
    handleSetDisplayNavigationPageNumbers(fetchedRequests.data.totalPages);
    setRequests(fetchedRequests.data.requests);
  };

  const handleSetDisplayNavigationPageNumbers = (totalPages) => {
    const tempArray = [];
    if(totalPages < 4) {
      for(let i = 1; i <= totalPages; i++) {
        tempArray.push(i);
      }
      setDisplayRequestNavigationNumbers(tempArray);
    }
    else if (totalPages >= 4) {
      for(let i = 1; i <= 3; i++) {
        tempArray.push(i);
      }
      setDisplayRequestNavigationNumbers(tempArray);
    }
  };
 
  useEffect(() => {
    getRquests();
  }, [url, status, sortDirection, sortField, timeRange, currentPage]);


  const toggleRequestModal = () => {
    setIsRequestModalOpen(!isRequestModalOpen);
  };

  const showRequestDetails = (request) => {
    toggleRequestModal();
    setRequestDetails(request);
  };
  
  const onClickApprove = async () => {
    try {
      const updatedRequest = { ...requestDetails, status: "APPROVED" };
      await axios.put(`${url}/${requestDetails.id}`, updatedRequest);
      setRequests(prevRequests =>
        prevRequests.map(req =>
          req.id === requestDetails.id ? { ...req, status: "APPROVED" } : req
        )
      );
      toggleRequestModal();
    } catch (error) {
        console.error("Error approving request:", error);
    }
  };

  const onClickDecline = async () => {
    try {
      const updatedRequest = { ...requestDetails, status: "DECLINED" };
      await axios.put(`${url}/${requestDetails.id}`, updatedRequest);
      setRequests(prevRequests =>
        prevRequests.map(req =>
          req.id === requestDetails.id ? { ...req, status: "DECLINED" } : req
        )
      );
      toggleRequestModal();
    } catch (error) {
        console.error("Error declining request:", error);
    }
  };

  // nac jednostavnije rjesenje ?
  const filterByTime = () => {
    setSortField("timeCreated");
    {sortDirection === "DESC" ? setSortDirection("ASC") : setSortDirection("DESC")};
  }; 

  const showStatusDropdown = () => {
    setIsStatusDropdownOpen(!isStatusDropdownOpen);
  };

  const handleSetStatus = (s) => {
    setStatus(s);
    showStatusDropdown();
  };

  const showTimeRangeDropdown = () => {
    setIsTimeRangeDropdownOpen(!isTimeRangeDropdownOpen);
  };

  const handleSetTimeRange = (timeRange) => {
    setTimeRange(timeRange);
    showTimeRangeDropdown();
  };

  const handlePageInc = () => {
    setCurrentPage((prevPage) => {
      return prevPage + 1;
    });
  };

  const handleNavigateNext = () => {
    /* handlePageInc(); */
    console.log("TEST currentPage: ", currentPage);
    if(currentPage <= totalPages) {
      setDisplayRequestNavigationNumbers((prevValues) => {
        return prevValues.map((pageNum) => pageNum + 1);
      });
      console.log("displayRequestNavigationNumbers: ", displayRequestNavigationNumbers);
    }
  };

  const handleNavigatePrev = () => {
    if(displayRequestNavigationNumbers[0] > 1) {
      setDisplayRequestNavigationNumbers((prevValues) => {
        return prevValues.map((pageNum) => pageNum - 1);
      });
    }
  };

  return(
    <>
      <Sidebar reqCount={requests.length}/>
      <div className="text-white grid justify-center items-center mt-20 sm:ml-60">

        <div className="relative flex justify-between mr-[70px] text-xs py-1 sm:mr-[75px] md:mr-[80px] 2xl:mr-[93px]">

          <button onClick={showTimeRangeDropdown} className="text-white bg-blue-700 hover:bg-blue-800 px-2 py-1 rounded-lg mb-2 lg:px-[10px] lg:py-[6px] 2xl:text-sm">
            <span className="flex justify-center items-center">
              {timeRange}
              <span className="ml-1"><IoIosArrowDropdown /></span>
            </span>
          </button>

          <button onClick={showStatusDropdown} className="text-white bg-blue-700 hover:bg-blue-800 px-2 py-1 rounded-lg mb-2 lg:px-[10px] lg:py-[6px] 2xl:text-sm">
            <span className="flex justify-center items-center">
              {status}
              <span className="ml-1"><IoIosArrowDropdown /></span>
            </span>
          </button>

          {isTimeRangeDropdownOpen && (
            <div className="absolute bg-[#001E28] text-center rounded-lg py-2 w-24 mt-1 top-[34px] z-10 2xl:text-sm 2xl:py-3 2xl:w-44 2xl:top-11">
              <ul>
              {timeRangeList.map((tr, index) => {
                return(
                  <li key={index} onClick={() => handleSetTimeRange(tr)} className="px-3 py-1 hover:bg-[#002a39] cursor-pointer" >{tr}</li>
                );
              })}
              </ul>
            </div>
          )}

          {isStatusDropdownOpen && (
            <div className="absolute bg-[#001E28] text-center rounded-lg py-2 w-24 mt-1 top-[34px] -right-2 z-10 2xl:text-sm 2xl:py-3 2xl:w-32 2xl:-right3 2xl:top-11">
              <ul>
                {statusList.map((status, index) => {
                  return(
                    <li key={index} className="px-3 py-1 hover:bg-[#002a39] cursor-pointer"  onClick={() => handleSetStatus(status)}>{status}</li>
                  );
                })}
              </ul>
            </div>
          )}
        </div>


        <table className="text-[11px]  md:text-[13.5px] lg:text-[14.5px] xl:text-[15.5px] 2xl:text-[16.5px]">
          <thead className="bg-[#001E28]">
            <tr>
              <th className="p-2">
                Requested by
              </th>
              <th className="p-2">
                <button onClick={filterByTime} type="button" className="flex justify-center items-center lg:ml-4 xl:ml-5">
                  Request time <span className="ml-3"><CiFilter /></span>
                </button>
              </th>
              <th className="p-2">
                Status 
              </th>
            </tr>
          </thead>
          <tbody>
            {requests.map((request) => {
              return(
                <tr key={request.id}>
                  <td className="p-1 lg:py-[6px] lg:px-[16px] 2xl:px-[20px]">
                    {request.requester.email}
                  </td>
                  <td className="p-1 lg:py-[6px] lg:px-[16px] 2xl:px-[20px]">
                    {request.timeCreated.slice(0, 10)} {request.timeCreated.slice(11, 19)}
                  </td>
                  <td className="p-1 lg:py-[6px] lg:px-[16px] 2xl:px-[20px]">
                    {request.status}
                  </td>
                  <td>
                    <span className={`h-[5px] w-[5px] rounded-2xl inline-block text-end mb-[1px] ml-[1px] ${request.status === 'APPROVED' ? 'bg-green-400' : request.status === 'DECLINED' ? 'bg-red-400' : 'bg-yellow-200'} lg:h-[6px] lg:w-[6px] 2xl:h-[7px] 2xl:w-[7px]`}></span>
                  </td>
                  <td>
                    <button
                      type="button"
                      className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-blue-300 font-medium rounded-lg text-[10px] px-[6px] py-[3px] me-2 mb-2 focus:outline-none ml-4 
                        md:text-[12px] lg:px-[8px] lg:py-[4px] 2xl:text-base
                      "
                      onClick={() => showRequestDetails(request)}
                      >
                      Open
                    </button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
        <div className="text-center pt-4 flex justify-center items-center">
          <button onClick={handleNavigatePrev} className={`text-white text-lg bg-slate-500 p-1 rounded-2xl cursor-pointer mr-2 `}><GrFormPrevious /></button>
          {displayRequestNavigationNumbers.map((page) => {
            return(
              <div key={page} className="px-2">
                <button key={page} className= {`text-white ${page === currentPage ? 'border-b' : ''}`}>{page}</button>
              </div>
            );
          })}
           <button onClick={handleNavigateNext} className={`text-white text-lg bg-slate-500 p-1 rounded-2xl cursor-pointer mr-2`}><MdNavigateNext /></button>
        </div>

        <div>
          {isRequestModalOpen && requestDetails && (
            <div className={`fixed inset-0 z-50 flex justify-center items-center bg-black bg-opacity-75 ${isRequestModalOpen ? '' : 'hidden'}`}>
              <div className="relative p-4 w-[95%] max-w-2xl max-h-full bg-gray-100 rounded-xl shadow-2xl shadow-gray-500">
                <div className="flex items-center justify-between p-4 border-b-2 rounded-t border-gray-300">
                  <h3 className="text-xl font-semibold text-gray-900">
                    Request details
                  </h3>
                  <button
                    onClick={toggleRequestModal}
                    className="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-2"
                  >
                    <svg
                      className="w-3 h-3"
                      aria-hidden="true"
                      xmlns="http://www.w3.org/2000/svg"
                      fill="none"
                      viewBox="0 0 14 14"
                    >
                      <path
                        stroke="currentColor"
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        strokeWidth="2"
                        d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
                      />
                    </svg>
                  </button>
                </div>
                <div>
                  <p className="text-black px-2 py-4">
                    {requestDetails.message}
                  </p>
                </div>
                <button onClick={onClickApprove} type="button" className="focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2">
                  Approve
                </button>
                <button onClick={onClickDecline} type="button" className="focus:outline-none text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 ">
                  Decline
                </button>
              </div>
            </div>
          )}
        </div>

      </div>
    </>
  );
}
export default Requests;

Why does import in node only work with .js file extension?

If I make a script.js and add:

import * as fs from 'node:fs';   

And then run with:

node script.js

It gives me a message and then reparses the script, but it still runs:

> Warning: Module type of
> file:///path_to_file/script.js is
> not specified and it doesn't parse as CommonJS. Reparsing as ES module
> because module syntax was detected. This incurs a performance
> overhead. To eliminate this warning, add "type": "module" to NodeJSProjectpackage.json.

This is understandable. If I change the file extension to anything other than .js, like .ts or .blah. I get the error:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".blah" for path/NodeJSProjectscript.blah
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:219:9)
    at defaultGetFormat (node:internal/modules/esm/get_format:245:36)
    at defaultLoad (node:internal/modules/esm/load:120:22)
    at async ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:514:32)
    at async ModuleJob._link (node:internal/modules/esm/module_job:115:19) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'

Ordinarily .blah or .ts would run Javascript if run by Node, but if using the import keyword it specifically has to be .js.

Oh, and I know by default Node runs in CommonJS mode, and you should have a package.json to specify module mode, that’s why I got the message:

Reparsing as ES module
> because module syntax was detected.

My question is why the .js extension is needed out of curiosity.

Regex to remove substrings such as “Official Video”, “Audio”, “Music Video”… from string

I’m trying to clean YouTube video title from unnecessary words such as “Official Video”, “Audio”, “Music Video” etc. I need help constructing regex that I can use. What I tried so far:

[(-]?s?official|videos?[)]?

I have problem that I can’t match spaces between words. If you have any easier regex, I would appreciate it. I will give a few examples of what I need to remove. It’s pretty standard words that appear in YouTube titles.

Audio
Video
Lyrics
Official
Remaster
...

And all those words (and maybe more) can appear between ( and ) or between [ and ] or after -. Those words can be combined, for example: Some title - Official Video which should be cleaned to be Some title etc.

Thanks in advance.

Office Js – OnChange not detect other services

I have a project in Office Js with Angular.

I have a code that is triggered when a cell changes its value.
Also, I have services that contain business logic

I want to use those methods inside the onchange but it doesn’t recognize them

Why can’t I use other methods/service inside OnChanges?

How to Get the PDF attachments from Gmail JavaScript

`async fetch_pdf_attachment(from_email, to_address, subject, body, downloadPath = “./Data/Files/”) {
let count = 0;
let email = null;

    // Get access token
    const accessToken = await getAccessToken(
        gmail_data.CLIENT_ID,
        gmail_data.CLIENT_SECRET,
        gmail_data.REFRESH_TOKEN,
    );

    // Retry mechanism to find the email
    do {
        email = await checkInbox({
            token: accessToken,
            query: `from:${from_email} to:${to_address} subject:${subject} ${body} has:attachment`,
            format: 'full'  // Request full message format to get all parts
        });
        
        if (!email) {
            count += 1;
            console.log(`Email not found, retrying (${count}/5)...`);
            await CommonUtils.sleep(5);
        }
    } while (!email && count < 5);

    if (!email) {
        console.log("No matching email found after retries.");
        return null;
    }

    // Ensure the download directory exists
    if (!fs.existsSync(downloadPath)) {
        fs.mkdirSync(downloadPath, { recursive: true });
    }

    try {
        // Find the PDF attachment part
        let pdfPart = null;
        
        // Function to find PDF part in message structure
        function findPdfPart(part) {
            if (part.mimeType === 'application/pdf' && part.body && part.body.attachmentId) {
                return part;
            }
            
            if (part.parts) {
                for (const subpart of part.parts) {
                    const found = findPdfPart(subpart);
                    if (found) return found;
                }
            }
            
            return null;
        }
        
        // Start search from the message payload
        pdfPart = findPdfPart(email.payload);
        
        if (!pdfPart) {
            console.log("No PDF attachment found in the email.");
            return null;
        }
        
        console.log(`Found PDF attachment: ${pdfPart.filename || 'unnamed.pdf'}`);
        
        // Get the attachment data
        const attachmentData = await checkInbox({
            token: accessToken,
            messageId: email.id,
            attachmentId: pdfPart.body.attachmentId
        });
        
        if (!attachmentData || !attachmentData.data) {
            console.log("Could not retrieve attachment data.");
            return null;
        }
        
        // Save the PDF file
        const filename = pdfPart.filename || 'attachment.pdf';
        const filePath = path.join(downloadPath, filename);
        
        const decodedData = Buffer.from(attachmentData.data, 'base64');
        fs.writeFileSync(filePath, decodedData);
        
        console.log(`PDF saved at: ${filePath}`);
        return filePath;
        
    } catch (error) {
        console.error(`Error processing email attachment: ${error.message}`);
        return null;
    }
}`

What modification’s need to be done to get the attachments from the email, The current code is going nested. It’s having an nested mime structure . how to overcome this

It’s finding the part which has the attachment application/pdf, even then using the attachment id was trying to retrieve the data, but again that part is having two parts one is text/html and application/pdf. It’s going nested and becoming an infinite loop.

Nifi API gives 400 invalid request from NodeJs Axios (works fine through curl or postman)

I have Apache nifi running locally.

I am able to access api url as below (generated from postman).

curl --location --insecure ^
  "https://localhost:8443/nifi-api/access/token" ^
  --header "Content-Type: application/x-www-form-urlencoded" ^
  --header "Cookie: __Secure-Authorization-Bearer=eyJraWQiOiI5OTU0MTZiYy1jMWQxLTQ4NGEtYmViYS0wYWU3MzFlYTkzOTgiLCJhbGciOiJFZERTQSJ9.eyJzdWIiOiI0MjBiNTI5NC1kYjczLTRhMjAtOWJkMi1jMmZjOTkxNzYxMTUiLCJhdWQiOiJodHRwczovL2xvY2FsaG9zdDo4NDQzIiwibmJmIjoxNzQxMjU4OTYyLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo4NDQzIiwiZ3JvdXBzIjpbXSwicHJlZmVycmVkX3VzZXJuYW1lIjoiNDIwYjUyOTQtZGI3My00YTIwLTliZDItYzJmYzk5MTc2MTE1IiwiZXhwIjoxNzQxMjg3NzYyLCJpYXQiOjE3NDEyNTg5NjIsImp0aSI6ImEzNmE5ZWQzLWVhNzgtNDIyZS04NDlmLTBiMTMzMDg3YWI3MiJ9.mGn5lkq2ZBe7G7iY_l0RmdaOf7C3PXKsIlGkj0VOUB8JPAqBnXmoAugEQBfmNhReIZI6lNTc4WqzCs5PgVqsBA" ^
  --data-urlencode "username=420b5294-db73-4a20-9bd2-c2fc99176115" ^
  --data-urlencode "password=EV6rc7kwWGFKmox7egM6VYkCS5Wht2ay"

Same request is not working from axios stating 400 invalid request (attached nodejs file (also generated from postman))

// npm i --save axios qs
const axios = require('axios');
const qs = require('qs');
const https = require('https');

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

let data = qs.stringify({
  'username': '420b5294-db73-4a20-9bd2-c2fc99176115',
  'password': 'EV6rc7kwWGFKmox7egM6VYkCS5Wht2ay' 
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://127.0.0.1:8443/nifi-api/access/token',
  headers: { 
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  data: data,
  httpsAgent: new https.Agent({  
    rejectUnauthorized: false  // Ignore self-signed certificate
  })
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

Below is the response.

  message: "Request failed with status code 400",
  name: "AxiosError",
  code: "ERR_BAD_REQUEST",

What is missing?

Function does not work to get text from file into array in browser [closed]

I have the following code is meant to take a .txt file (that is a list of items separated by returns) and turn it into an array.

It works fine on a local http-server test, but when I put it on a host website online, it does not work. It seems to get the data just fine, but does not execute the .then statement which splits it. It creates the string- creates the array of length 1, but does not separate it.

function getDataFromTxt(fullFilePath) {
  const myRequest = new Request(fullFilePath);
  var toReturn;

  return fetch(myRequest)
    .then((response) => {
      if (!response.ok) {
        throw new Error(`HTTP error, status = ${response.status}`);
      }
      return response.text();
    })
    .then((text) => {
      toReturn = text;
      toReturn = toReturn.split("r");
      for (let i = 0; i < toReturn.length; i++){
          toReturn[i] = toReturn[i].replace('n','');
      }
      return toReturn;
    })
    .catch((error) => {
      toReturn = `Error: ${error.message}`;
    });
}

Using javascript, How make Hover div disappear

I am using a drop-down on my nav bar to execute functions.


    .dropdown-content_Mouse {
      display: none;
      position: absolute;
      background-color: #f9f9f9;
      z-index: 2;
    }
    
    .dropdown-content_Mouse a {
      float: none;
      color: black;
      text-decoration: none;
      display: block;
      text-align: left;
      font-size: 2vmin;
      padding-top: 1vmin;
      padding-right: 4vmin;
      padding-bottom: 1vmin;
      padding-left: 4vmin;
      
    }
    
    
    
    .dropdown-content_Mouse a:hover {
      background-color: #ddd;
    }
    
    .dropdown:hover .dropdown-content_Mouse {
      display: block;
    }
    
           <div class="dropdown">
             <button class="dropbtn">  Mouse Actions </button>
             <div class="dropdown-content_Mouse">
            <a href="javascript:Mouse_Cancel();">Cancel</a>
            <a href="javascript:Mouse_Reset();">Reset to Original</a>
            <a href="javascript:Mouse_VLine();">Vertical Line</a>
            <a href="javascript:Mouse_ClipR();">Clip Right</a>
            <a href="javascript:Mouse_ClipL();">Clip Left</a>
            <a href="javascript:Mouse_ClipTU();">Clip Temp Up</a>
            <a href="javascript:Mouse_ClipTD();">Clip Temp Down</a>
            <a href="javascript:Mouse_ClipVU();">Clip Pressure Up</a>
            <a href="javascript:Mouse_ClipVD();">Clip Pressure Down</a>
    
            </div>
            </div> 

The function executes but the drop-down is still visible unit the mouse is moved off the drop-down div. – I want to have the drop-down not visible as if the mouse caused it.

I’ve tried making the div display “none”, etc — all of those will disappear the div BUT Hover will never make it visible again – the Hover feature is no longer active.

Suggestions? Thanks.

Vite dev server having trouble handling # in public asset filenames

I have a vitejs+react+typescript project with filenames containing the # character, as in images/foo#2.png, images/foo#2.png and so on.
The dev server has some trouble interpreting this path, even if passed through encodeURIComponent() so # turns into %23, so the asset isn’t properly linked to.
I’d like to know if there’s something I can do to fix this, maybe with some middleware.

The obvious solution would be to rename the files, but that’s outside of my control as they’re in a third-party repository added as a submodule and would require forking and adding a build step / script to mass rename them in all folders, which is not ideal.

Attached is sample code reproducing the issue:

// main.js
document.querySelector('#app').innerHTML = `
  <div>
    <ul>
      vite.svg: <img src="vite.svg" /><br/>
      vite#2.svg with no encodeURIComponent: <img src="vite#2.svg" /><br/>
      vite#2.svg with encodeURIComponent: <img src="${encodeURIComponent(
        'vite#2.svg'
      )}" />
    </ul>
  </div>
`;

Folder Structure
Result

Question about Prisma indexes, response its slow

I just noticed that I haven an issue with one of my queries.
I have the following model on prisma:

model Subscriber {
  id         String        @id @default(uuid())
  timestamp  DateTime      @default(now())
  popup_id   String
  user_id    String
  session_id String?
  popup_type PopupTypeEnum
  user_agent String?
  referrer   String?
  url        String
  email      String
  code       String?

  @@index([user_id, timestamp(sort: Desc)])
}

The issue is that when I fetch a response with the orderBy its taking 1 min to answer. And if I remove the orderBy its instant. The db has aprox 200k rows because im testing.

const subscribers = await prisma.subscriber.findMany({
        where: whereClause,
        take: limit,
        orderBy: { timestamp: "desc" },
        ...(oldCursor ? { cursor: { id: oldCursor }, skip: 1 } : {}),
      });

If I remove the orderBy

const subscribers = await prisma.subscriber.findMany({
        where: whereClause,
        take: limit,
        ...(oldCursor ? { cursor: { id: oldCursor }, skip: 1 } : {}),
      });

Works perfectly, can someone help me I need to order the response how can I fix this? Already added the indexes on prisma but still taking like 1 min to answer…

I would appreciate if someone can point me on the right direction!.

Rows overlapping when resize window

While creating table using Grid it two columns are overlapping when resize the window, I am not much familiar with react so, this is my code below which I tried, but it results me in below image. Could you please help me in this? Also, will it be possible if we resize the window, then column which is overlapping comes below other column like a stack.

<Grid container spacing={4} sx={{ width: '100%' }}>
                {columns.map((column, colIndex) => (
                    <Grid item xs={12} sm={6} md={4} key={colIndex}>
                        <Box sx={{
                            display: 'flex', flexDirection: 'column', width: 'auto', position: 'relative',
                        }}>
                            <Table>
                                <TableBody>
                                    {column.map((row: FormattedValue, rowIndex: number) => (
                                        <TableRow
                                            key={rowIndex}
                                            sx={{
                                                '&:nth-of-type(odd)': {
                                                    backgroundColor: 'zebra.odd',
                                                },
                                                flexDirection: 'column',
                                                width: '100%',

                                            }}
                                        >
                                            {row.label && (
                                                <TableCell
                                                    component='th'
                                                    scope='row'
                                                    sx={{
                                                        p: 1,
                                                        pl: 2,
                                                        height: 32,
                                                        whiteSpace: 'pre',
                                                        flexDirection: 'column',
                                                    }}
                                                >
                                                    {row.label as string}:
                                                </TableCell>
                                            )}
                                            <TableCell
                                                align={row.label ? 'right' : 'left'}
                                                sx={{
                                                    p: 1,
                                                    pr: 2,
                                                    height: 32,
                                                    minWidth: 100,
                                                }}
                                            >
                                                <Typography
                                                    sx={{
                                                        color: 'primary.main',
                                                        fontSize: 14,
                                                    }}
                                                >
                                                    {render(row)}
                                                </Typography>
                                            </TableCell>
                                        </TableRow>
                                    ))}
                                </TableBody>
                            </Table>
                        </Box>
                    </Grid>
                ))}
            </Grid>
[![enter image description here][1]][1]


  [1]: https://i.sstatic.net/Tp6Cy6RJ.png