AppsScript – String.replace(/s/g,””) deletes one of the characters when the string contains at least 2 % signs separated by only whitespace

I encountered this weird bug while working on an internal library for my work. We use App Script which is based on Javascript. However, there is a weird quirk with the string.replace() function that is causing problems.

Managers often include spaces when sending commands to our email bot so we have a function in a library which removes whitespace. It is:

function cleanSpaces(string){
  return string.replace(/s/g,"")
}

This function works fine unless the string has at least 2 ampersands separated by at least 1 whitespace character and no other characters.

This is a problem because some of the commands sent to the email bot use special characters, including %s to encode data for the request. Inconsistent behaviors when processing the data could cause problems long term, and I don’t know if this bug affects any other special characters.

For testing, I made a function in apps script and a dummy html page. The apps script test function has the following code (with ‘testString’ replaced with the test string):

function myFunction() {
  let string = 'testString'
  Logger.log(cleanSpaces(testString))
}

And the html document has the following code (with ‘testString’ replaced with the test string):

<html><body>
<p id="test"></p>

<script>
let string = 'testString';
string = string.replace(/s/g,"");
document.getElementById("testString").innerHTML = string;
</script>

</body></html>

When the string is set to something like ‘Hello World’, both functions correctly output HelloWorld

When the string is set to something like ‘ % 4 %4% 4%’, both functions correctly output %4%4%4%

However, when the string is set to something like ‘% %’, the html document correctly outputs %% but the Apps Script incorrectly outputs %.

Could someone please let me know why this happens and what (if anything) can be done to fix it.

problems with sequelize intermediate table

10 days ago I come with this problem I run out of ideas. what happens is that I have a many to many relationship between the entities of orders and equipment that are borrowed. the problem is as follows, I OrdersEquipments model in which I request the id of each team and award them to the order to have a strict control. The problem is that in the forOf cycle when updating the fieldName with their respective model I load a column that should not be because it is not being requested which is pdasId as we will see in the console below:

beforeCreate console:


pcsId VAMOS BIEN OrdersEquipment {
  dataValues: { pdasId: null, orderId: 6, pcsId: 1 },
  _previousDataValues: { orderId: undefined, pcsId: undefined },
  uniqno: 1,
  _changed: Set(2) { 'orderId', 'pcsId' },
  _options: {
    isNewRecord: true,
    _schema: null,
    _schemaDelimiter: '',
    attributes: undefined,
    include: undefined,
    raw: undefined,
    silent: undefined
  },
  isNewRecord: true
}

CODE JS:

export const createOrder = async (req, res) => {
  try {
    const {
      responsibility,
      event,
      note,
      state,
      userId,
      pdaCount,
      handiesCount,
      pcsCount,
      printHardCount,
      printPocketCount,
      celusCount,
      complementsCount,
    } = req.body;

    const selectEquipment = async (model, count) => {
      const availableEquipments = await model.findAll({ where: { userId: 1 } });
      if (availableEquipments.length < count) {
        throw new Error(
          `No hay suficientes equipos disponibles de tipo ${model.name}`
        );
      }
      return availableEquipments.slice(0, count);
    };

    const selectedPDAs = await selectEquipment(PDAS, pdaCount);
    const selectedCelus = await selectEquipment(CELUS, celusCount);
    const selectedPCs = await selectEquipment(PCS, pcsCount);
    const selectedPrintHards = await selectEquipment(
      HARDTICKET,
      printHardCount
    );
    const selectedPrintPockets = await selectEquipment(
      POCKET,
      printPocketCount
    );
    const selectedHandies = await selectEquipment(HANDIES, handiesCount);
    const selectedComplements = await selectEquipment(
      COMPLEMENT,
      complementsCount
    );

    if (
      selectedPDAs.length === pdaCount &&
      selectedCelus.length === celusCount &&
      selectedPCs.length === pcsCount &&
      selectedPrintHards.length === printHardCount &&
      selectedPrintPockets.length === printPocketCount &&
      selectedHandies.length === handiesCount &&
      selectedComplements.length === complementsCount
    ) {
      const newOrder = await ORDERS.create({
        responsibility,
        event,
        note,
        state,
        userId,
      });

      const assignEquipmentsToOrder = async (equipments, model) => {
        for (const equipment of equipments) {
          console.log(model.name)
          const fieldName = `${model.name.toLowerCase()}Id`;

          const newOrderEquipment = {
            orderId: newOrder.id,
            [fieldName]: equipment.id,
          };
    await ordersEquipmentModel.beforeCreate((newOrderEquipment) => {
        if (newOrderEquipment[fieldName] != null) {
          console.log(fieldName, "VAMOS BIEN", newOrderEquipment);
        } else {
          console.log("VAMO MAL", newOrderEquipment);
        }
      });
          await ordersEquipmentModel.create(newOrderEquipment);

          equipment.userId = userId;
          await equipment.save();
        }
      };

      await assignEquipmentsToOrder(selectedPDAs, PDAS);
      await assignEquipmentsToOrder(selectedPCs, PCS);
      await assignEquipmentsToOrder(selectedPrintHards, HARDTICKET);
      await assignEquipmentsToOrder(selectedPrintPockets, POCKET);
      await assignEquipmentsToOrder(selectedCelus, CELUS);
      await assignEquipmentsToOrder(selectedHandies, HANDIES);
      await assignEquipmentsToOrder(selectedComplements, COMPLEMENT);

      return res.status(200).json(newOrder);
    } else {
      throw new Error("No se pudieron asignar todos los equipos solicitados.");
    }
  } catch (error) {
    return res.status(500).json({ message: error.message });
  }
};

I hope you can understand it is the first time I post in a forum, thank you very much!

I tried modifying the model relationships but the error persisted, also the controller logic. The only way I found that it works is when I make the post request and I don’t ask for any entity except the pdas in which the error is the following: “message”: “the null value in the column ‘pdasId’ of the relationship ‘OrdersEquipments’ violates the constraint of not null” and I tried adding the allowNull in the model orderEquipments and it didn’t work either.`

Have created HTML form – struggling to get it to send email to my client with the user input data from the form

I have been learning HTML, CSS and Javascript so far and have built an enquiries form on a website that I am building.

In order for my client to be able to easily gather the data that form users submit, I would like to get the form to send an email to her email address, with the information that the user has inputted, when they click the submit button.

I understand that I may need to use PHP to do this but I haven’t learnt any PHP yet, as I’ve not yet started back-end languages – I have been learning front-end so far.

I have included my HTML code below. I can provide the CSS code if needed. I would like some guidance as to: –

  • Whether it’s worth trying to work out how to do this through PHP yet, or whether it’s worth shelving the form functionality until further down the line when I have started learning back-end languages.
  • Whether there is an alternative simple way of enabling my client to gather the user data, bearing in mind that she does not have coding skills, that does not involve use of back-end languages (does not have to involve emailing her the form data, as long as it is simple for her to use).
  • Some guidance on how I would go about sorting this through PHP. I have seen snippets of PHP code that are relevant to this issue, but I am struggling to understand them.
            <form id="enquiriesForm" class="flex-item">
                <label for="firstName" class="flex-item"><h5><b>First Name</b></h5></label>
                    <input type="text" id="firstName" name="firstName" class="flex-item" required>
                <br />
                <label for="secondName" class="flex-item"><h5><b>Second Name</b></h5></label>
                    <input type="text" id="secondName" name="secondName" class="flex-item"                    required>
                <br />
                <label for="emailAddress" class="flex-item"><h5><b>Email Address</b></h5></label>
                    <input type="email" id="emailAddress" name="emailAddress" class="flex-item" required>
                <br />
                <label for="phoneNumber" class="flex-item"><h5><b>Phone Number <h6><b>(optional field)</b></h6></b></h5></label>
                    <input type="number" id="phoneNumber" name="phoneNumber" class="flex-item">
                <br />
                <h5 class="flex-item"><b>Please choose the services that you are interested in</b></h5> <h6><b>(you can select more than one option)</b></h6>
                    <input type="checkbox" id="option1" name="option" value="blockOfFourClasses" class="flex-item">
                        <label for="option1" class="flex-item"><b>Block of Four Classes at Venue</b></label>
                    <input type="checkbox" id="option2" name="option" value="privateTuitionOwnHome" class="flex-item">
                        <label for="option2" class="flex-item"><b>Private Tuition in my Own Home</b></label>    
                    <input type="checkbox" id="option3" name="option" value="privateTuitionStudio" class="flex-item">
                        <label for="option3" class="flex-item"><b>Private Tuition in Mirrored Studio</b></label>
                    <input type="checkbox" id="option4" name="option" value="antenatalConsultation" class="flex-item">
                        <label for="option4" class="flex-item"><b>Antenatal Consultation</b></label>
                <br />
                <h5 class="flex-item"><b>Do you want to be added to our mailing list?</b></h5>
                    <input type="radio" id="radio1" name="yesNo" value="yes" class="flex-item">
                        <label for="radio1" class="flex-item"><b>Yes</b></label>
                    <input type="radio" id="radio2" name="yesNo" value="no" class="flex-item">
                        <label for="radio2" class="flex-item"><b>No</b></label>
                <br />
                <label for="freeTextComments" class="flex-item"><h5><b>Please Type Your Enquiry Here</b></h5></label>
                    <textarea id="comment" name="comment" rows="4" cols="30" class="flex-item"></textarea>
                <br />
                <br />   
                <button type="button" id="submitButton" class="flex-item"><span><h4><strong>Submit</strong></h4></span></button> 
</form>

I was ideally trying to avoid using a Javascript function to process the user input, unless I can get the Javascript function to email the users’ input to my client (which I understand that I can’t). This is because I presumed that a Javascript function would be too complicated for someone who does not how to code to access the user data.

If I am wrong on this and there is a relatively simple way of sorting this, and her accessing the user data, through Javascript, I would appreciate some guidance on this.

Why does el.scrollIntoView() cause the whole container to move?

I have nested overflow-y: auto elements, with a full page which is scrollable, and the sidebar which is independently scrollable. When I hover on something in the main content area, I want the sidebar nav link to scroll into view (to the top or center, if possible), but when I call sideBarNavLink.scrollIntoView(), it scrolls the entire content/page so the whole content goes up and is cut off on the bottom. My page is relatively complicated to reproduce.

Is there some trick to making scrollIntoView reliable and work as you’d expect? Do I need position: relative and stuff like that to get it to work or something? Or do I need to roll my own scroll into view function?

$(document).ready(() => {
  $('.link').click((e) => {
    e.currentTarget.scrollIntoView({ behavior: 'smooth', block: 'start' })
  })
})
.page {
  padding: 16px;
  background: yellow;
  display: flex;
  width: 100%;
  height: 300px;
  overflow-y: auto;
}

.content {
  padding: 16px;
  background: blue;
  flex: 1;
}

.sidebar {
  padding: 16px;
  background: pink;
  overflow-y: auto;
  height: 100%;
  width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="page">
  <div class="sidebar">
    <ul>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
      <li class="link">a</li>
    </ul>
  </div>
  <div class="content">
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
  </div>
</div>

Notice when you click on an “a” (a .link class), it scrolls the whole StackOverflow post into view! Why…

How to Run a Specific Spec File During `globalSetup` in Playwright?

I’m trying to run a specific spec file (math.spec.js) during the globalSetup phase in Playwright. The goal is to execute this spec file before any other tests run.

Here’s the structure of my project:

/my-project
|-- tests/
|   |-- e2e/
|       |-- pos/
|           |-- math.spec.js
|-- playwright.config.js
|-- global-setup.js

In global-setup.js, I want to run the math.spec.js file using the Playwright test runner. I’ve tried using Node’s child_process to execute the command, but I’m not sure if this is the best approach or if there is a built-in way in Playwright to handle this.

global-setup.js:

const { execSync } = require('child_process');

module.exports = async () => {
  try {
    // Attempt to run the specific spec file
    execSync('npx playwright test tests/e2e/pos/math.spec.js', { stdio: 'inherit' });
  } catch (error) {
    console.error('Error running math.spec.js in global setup:', error);
    process.exit(1); // Exit with a failure code if the test fails
  }
};

playwright.config.js:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  globalSetup: require.resolve('./global-setup.js'),
  // Other configurations...
});

Questions:

  • Is this the correct way to run a specific spec file during globalSetup in Playwright?
  • Are there any best practices or potential issues with this approach?
  • Is there a more Playwright-native way to achieve this?

I’m using Playwright version 1.46.1 and Node.js version 20.15.1.

Injected contentScript via background.js is not respecting match pattern

Expected behaviour

For injected content script to run on specific pages that I set within my manifest.json

Current behaviour

Contentscript is injected on every page. Or atleast I seem to see errors in console for background indicating background.js:1 Uncaught (in promise) Error: Cannot access contents of url... ". Maybe it’s working but I don’t want to see these errors!

Manifest.json – I also tried host_permission as I understand this is relevant permission for programmatic injection

{
  "content_scripts": [
    {
      "matches": [
        "https://example-01.au/*",
        "https://example-03.com/*",
        "https://example-02.eu/*"
      ],
      "js": ["contentscript.js"]
    }
  ],
  "permissions": [
    "tabs",
    "contextMenus",
    "offscreen",
    "clipboardWrite",
    "tabGroups",
    "storage",
    "scripting",
    "activeTab"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "host_permissions": [
    "https://example-01.au/*",
    "https://example-03.com/*",
    "https://example-02.eu/*"
  ]
}

Background.js

chrome.tabs.onActivated.addListener((info) => {
  chrome.tabs.get(info.tabId, (tab) => {
    if (tab.url?.startsWith('chrome://')) return undefined;
    chrome.scripting
      .executeScript({
        target: { tabId: info.tabId },
        files: ['contentScript.js']
      })
      .then(() => {
        console.log('Scripted Injected');
      });
  });
});

It’s not clear from the docs. But, do ineed to programmatically set up page matches within my background.js?

JS Start date system [closed]

I work for a college, and we have specific start dates for each program. Most programs have a monthly start date while others skip a few months.

I want to write a code whereby we can update the start dates and cut off dates yearly, and it will display the next two upcoming start dates.

My idea is to define start dates and cut off dates, get the current date, create arrays for each “set” of start dates and each “set” of cut off dates, then compare the current date to the cut off dates and create new variables from the start date arrays with only the next two upcoming start dates in it.

// Set start dates for each month - Update yearly:
const janStartDate = "January 29";
const febStartDate = "February 26";
const marStartDate = "March 25";
const aprStartDate = "April 29";
const mayStartDate = "May 27";
const junStartDate = "June 24";
const julStartDate = "July 29";
const augStartDate = "August 26";
const sepStartDate = "September 30";
const octStartDate = "October 28";
const novStartDate = "November 25";
const decStartDate = "December 16";

// Set cut off dates - Update yearly:
const janCut = new Date(2024, 0, 19);
const febCut = new Date(2024, 1, 16);
const marCut = new Date(2024, 2, 15);
const aprCut = new Date(2024, 3, 19);
const mayCut = new Date(2024, 4, 17);
const junCut = new Date(2024, 5, 14);
const julCut = new Date(2024, 6, 19);
const augCut = new Date(2024, 7, 16);
const sepCut = new Date(2024, 8, 20);
const octCut = new Date(2024, 9, 18);
const novCut = new Date(2024, 10, 15);
const decCut = new Date(2024, 11, 13);

// Get current date:
const currentDate = new Date();
const currentMonth = currentDate.getMonth();

// Create arrays of cut off dates:
const monthlyCutOffDates = [janCut, febCut, marCut, aprCut, mayCut, junCut, julCut, augCut, sepCut, octCut, novCut, decCut]
const phrmCutOffDates = [febCut, marCut, mayCut, junCut, augCut, sepCut, novCut, decCut]
const techCutOffDates = [janCut, marCut, aprCut, junCut, julCut, sepCut, octCut, decCut]
const pswCutOffDates = [janCut, febCut, marCut, aprCut, mayCut, junCut, julCut, augCut, sepCut, novCut, decCut]

// Create arrays of start dates:
const monthlySet = [janStartDate, febStartDate, marStartDate, aprStartDate, mayStartDate, junStartDate, julStartDate, augStartDate, sepStartDate, octStartDate, novStartDate, decStartDate];
const phrmSet = [febStartDate, marStartDate, mayStartDate, junStartDate, augStartDate, sepStartDate, novStartDate, decStartDate];
const techSet = [janStartDate, marStartDate, aprStartDate, junStartDate, julStartDate, sepStartDate, octStartDate, decStartDate];
const pswSet = [janStartDate, febStartDate, marStartDate, aprStartDate, mayStartDate, junStartDate, julStartDate, augStartDate, sepStartDate, novStartDate, decStartDate];

// Limit the start date sets to only the two upcoming start dates:
let monthlyStartDatesToShow = [];
if (currentDate > monthlyCutOffDates[currentMonth]) {
    monthlyStartDatesToShow.push(monthlySet[(currentMonth + 1)]);
    monthlyStartDatesToShow.push(monthlySet[(currentMonth + 2)]);
}
else {
    monthlyStartDatesToShow.push(monthlySet[currentMonth]);
    monthlyStartDatesToShow.push(monthlySet[(currentMonth + 1)]);
}
let phrmStartDatesToShow = [];
if (currentDate > phrmCutOffDates[currentMonth]) {
    phrmStartDatesToShow.push(phrmSet[(currentMonth + 1)]);
    phrmStartDatesToShow.push(phrmSet[(currentMonth + 2)]);
}
else {
    phrmStartDatesToShow.push(phrmSet[currentMonth]);
    phrmStartDatesToShow.push(phrmSet[(currentMonth + 1)]);
}
let techStartDatesToShow = [];
if (currentDate > phrmCutOffDates[currentMonth]) {
    techStartDatesToShow.push(techSet[(currentMonth + 1)]);
    techStartDatesToShow.push(techSet[(currentMonth + 2)]);
}
else {
    techStartDatesToShow.push(techSet[currentMonth]);
    techStartDatesToShow.push(techSet[(currentMonth + 1)]);
}
let pswStartDatesToShow = [];
if (currentDate > pswCutOffDates[currentMonth]) {
    pswStartDatesToShow.push(pswSet[(currentMonth + 1)]);
    pswStartDatesToShow.push(pswSet[(currentMonth + 2)]);
}
else {
    pswStartDatesToShow.push(pswSet[currentMonth]);
    pswStartDatesToShow.push(pswSet[(currentMonth + 1)]);
}

// Assign start date sets to pages:
switch ({post_id}) {
    case 96:
        document.getElementById("start-date-1").innerHTML = phrmStartDatesToShow;
        break;
    case 1420:
        document.getElementById("start-date-1").innerHTML = pswStartDatesToShow;
        break;
    case 1411:
    case 1422:
        document.getElementById("start-date-1").innerHTML = techStartDatesToShow;
        break;
    default:
        document.getElementById("start-date-1").innerHTML = monthlyStartDatesToShow;
        break;
}

monthlyStartDatesToShow is working great, but the others are not. They either display only one date (which is incorrect, December), or neither.

How to generate GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET without a domain?

I would like to create a new Google API project for a nextJS webapp. I cannot understand how to get the API GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET without a domain.

I have to setup in the .env file

# Next Auth Google provider
GOOGLE_CLIENT_ID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
GOOGLE_CLIENT_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

I tried looking for solutions but I cannot find the resources.Screenshot showing the options

Error in VS Code for not deploying express server

My vs code is not showing any links for running the express js server and there is no error in the code and every package is perfectly installed and previously it was running

I have done like every thing I could possibly think of like creating a new folder, downloading and enabling extensions and reinstalling vs code also

How to debug an unknown issue in GMaps JS API

A map editor implementation for Google Maps’ JS API suddenly stopped working.

I have a WordPress plugin with a backend that provides a “map editor” – the way it works is by rendering a GMap and providing an UI that allows you to place a marker on that map, retrieve the click location/coords and save it into the database. The frontend is pretty simple as well – it takes the markers and infowindow data from the db and renders the map.

The frontend is fine, however when a map is loaded through the editor – the map renders for a split second, like a flash, and then goes to “Oops! Something went wrong. – This page didn’t load Google Maps correctly. See the JavaScript console for technical details.”. I don’t identify any clues in the browser console.

How should I approach this?

API key and cloud settings are valid.

I tried loading a completely empty map – no markers or other config. Didn’t work. Frontend on the other hand loads fine and contains the same yellow warnings in the console.

P.S: this happened out of nowhere, there hasn’t been any updates or changes to the environment. The downside is that this is a vue.js implementation and the source files are unavailable, so I am stuck debugging output JS.

MathJax not rendering after refresh page

In order to understand how MathJax works, I have developed a very basic and simple html file (called test.html) with some MathJax equations:

<html>

    <!-- Module for rendering Markdown content -->
    <script type="module" src="https://md-block.verou.me/md-block.js"></script>

    <!-- Module for rendering mathematical equations -->
    <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

    <body>
        <md-block>

            Let's solve a simple second-order homogeneous linear differential equation with constant coefficients. One common example is:

            [
            y'' - 5y' + 6y = 0
            ]

            To solve this, we'll find the characteristic equation by assuming a solution of the form ( y = e^{rt} ), where ( r ) is a constant. The derivative terms ( y' ) and ( y'' ) become ( re^{rt} ) and ( r^2e^{rt} ) respectively, leading to the characteristic equation:

            [
            r^2 - 5r + 6 = 0
            ]

            This quadratic can be factored as:

            [
            (r - 2)(r - 3) = 0
            ]

            So, ( r_1 = 2 ) and ( r_2 = 3 ) are the roots. Therefore, the general solution of the differential equation is:

            [
            y(t) = c_1e^{2t} + c_2e^{3t}
            ]

            Here, ( c_1 ) and ( c_2 ) are constants determined by initial conditions, which are not given in this context. Thus, we have the general form of the solution.

        </md-block>
    </body>
</html>

Now, if I open with Google Chrome the test.html file, the equations render perfectly, but when I refresh the page using the refresh button of Chrome, the euqations are shown in their row form. I have to wait around a couple of minutes to have the equations properly rendered in MathJax format.

Do you know what could be the reason and how should I edit this file in order to have a properly working code?

Strapi (v4.x): Difficulty Refreshing Expired JWT Token Due to Lack of User ID

I’m facing an issue with refreshing an expired JWT token in my application. The problem is that when a token expires, I can no longer retrieve the user’s ID because the token is invalid, and I need the user’s ID to generate a new token.

Here’s a brief overview of the situation:

  1. Problem Description: When a user’s JWT token expires, I cannot
    extract the user’s ID from the expired token because the
    verification process fails due to the token’s expiration. Without
    the user ID, I can’t issue a new JWT token.

  2. Current Approach: I’m using the following approach to verify the
    token and issue a new token:

 plugin.controllers.auth.refreshToken = async (ctx) => {
    const params = _.assign(ctx.request.body);

    try {
      const { id } = await strapi.plugins[
        "users-permissions"
      ].services.jwt.verify(params.jwt); // Problem retrieving user id, if token expires.

      const RAW_SQL = `SELECT id FROM up_users WHERE id = ${id}`;

      const entriesResult = await strapi.db.connection.raw(RAW_SQL);
      const rows = entriesResult.rows;

      if (_.size(rows) === 1) {
        const user = _.first(rows);

        ctx.send({
          jwt: strapi.plugins["users-permissions"].services.jwt.issue({
            id: user.id,
          }),
        });
      }
    } catch (e) {
      return ctx.badRequest(null, "Invalid token");
    }
  };

aes256 dbms_crypto output mismatches with crypto-js

I am trying to match PLSQL dbms_crypto with Javascript crypto-js. I want to encrypt in JS and decrypt in PLSQL, but for testing, I am encrypting in both to see if I can get the encrypted value to match.

I followed this as much as I could but I am still stuck.

dbms_crypto output mismatches with crypto-js

PLSQL

    FUNCTION cl_encrypt (p_string VARCHAR2, p_key VARCHAR2)
        RETURN VARCHAR2
    AS
        lv_whats_my_name    VARCHAR2 (100) := 'cl_utilities.cl_encrypt';
        v_encrypted_raw     RAW (32000);
        v_key               RAW (320);
        v_encryption_type   PLS_INTEGER := DBMS_CRYPTO.encrypt_aes256 + DBMS_CRYPTO.chain_cbc + DBMS_CRYPTO.pad_pkcs5;
    BEGIN
        v_key   := RAWTOHEX (UTL_I18N.string_to_raw (p_key, 'AL32UTF8'));
        v_encrypted_raw   :=
            DBMS_CRYPTO.encrypt (src => UTL_I18N.string_to_raw (p_string, 'AL32UTF8'), typ => v_encryption_type, key => v_key,iv=>utl_raw.cast_to_raw(1));

       RETURN UTL_RAW.cast_to_varchar2 (UTL_ENCODE.base64_encode (v_encrypted_raw));

    END;

Javascript

const CryptoJS = require('crypto-js');

const key = 'some key phrase to 0129034676438'
const message = 'bob is your uncle'
var encrypted = CryptoJS.AES.encrypt(
    message,
   CryptoJS.enc.Base64.parse( Buffer.from(key).toString('hex')),
    { iv: CryptoJS.enc.Utf8.parse(1), mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });

console.log("encrypted vaule :: " + encrypted );


```
Key : 'some key phrase to 0129034676438'
message: 'bob is your uncle'
iv: 1

Plsql Encrypted value
UiJjrdgefVCcY1aJNuIt+oPPAPNOtnVTsE1g3sOwxiU= 

Javascript value
 
3UcXtyd9amnyjCYXKqi4ZrqB48ZerohDON80i1h4v2U=