Google App script send data to backend, how to authorize request?

I’m using a google app script to get data on change and sending it to my backend. All of it is working correctly but now I want to add authentication meaning that the request is coming from the app script connected to the correct google cloud project.

here is my manifes scopes

  "oauthScopes": [
    "openid",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/cloud-platform",
    "https://www.googleapis.com/auth/spreadsheets.currentonly"
  ]

here is function

async function syncWithBackend(payload) {
  const ui = SpreadsheetApp.getUi();

  const options = {
    method: "post",
    headers: { 
      "Content-Type": "application/json",
      Authorization: `Bearer ${ScriptApp.getOAuthToken()}` },
    payload: JSON.stringify(payload),
  };

  try {
    const res = UrlFetchApp.fetch('backend-url', options);
    const responseText = res.getContentText();
    ui.alert('Response from backend: ' + responseText); 
  } catch (error) {
    ui.alert('Error communicating with backend: ' + error.message + ScriptApp.getIdentityToken()); // Handle errors
  }
}

On my backend I check the following


const CLIENT_ID = ''

export async function verifyGoogleOAuthToken(token: string) {
  const client = new OAuth2Client(CLIENT_ID)

  try {
    const ticket = await client.verifyIdToken({
      idToken: token,
      audience: CLIENT_ID, // Ensure this matches your project's client ID
    })

    const payload = ticket.getPayload()
    console.log('Verified payload:', payload)

    // Check the email or project association if needed
    if (payload.iss !== 'https://accounts.google.com') {
      throw new Error('Invalid issuer')
    }

    return payload
  } catch (error) {
    console.error('Token verification failed:', error.message)
    throw error
  }
}

but I get the following error Wrong number of segments in token

Preferably I would like to use google service account to validate

what should I do?

Content Security Policy is blocking outgoing requests

I have very strange problem which I can’t figure out.

I will use example.com, but my domain is publicly accessible URL.

I have meta element set in my HTML:

<meta http-equiv="content-security-policy" content="default-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' https://example.com;">

Note the connect-src 'self' https://example.com;".

However, if I try to request the URL with fetch like below:

const response = await fetch(baseUrl + generatePath, {
    method: 'POST',
    headers: {
        Authorization: 'Bearer 1234',
        'Content-Type': 'text/event-stream',
    },
    body: JSON.stringify(requestBody),
})

The request is not even made, and i can see the error in browser’s console:

Refused to connect to ‘https://example.com/api/generate’ because it violates the following Content Security Policy directive: “default-src ‘self'”. Note that ‘connect-src’ was not explicitly set, so ‘default-src’ is used as a fallback.

Which is extremely strange, because i have it set.

Which is more strange, when I run it on locahost:5173, the request is made, on port 3000 it fails.

The same happens when I deploy it to Azure and access it from different domain.

And I just don’t know how to solve it. I have seen similair questions about HTTP request headers, but there is no request made at all.

It happens on Chrome and Opera browsers.

Unable to login to SSO based application using playwright tool

I’m doing a playwright POC for an application where I’m facing an issue to login into an application using playwright, though manually I’m able to login.

Here is thing after entering the credentials. I’m getting a blank screen.

Can Someone pls help because this is the issue with the playwright because in my team some of the guys are using the Tosca tool for automation and they are able to login using SSO login as well as external user login.

I have try like i do some changes in the code and run the script in non- incognito mode but still issue exist because playwright by default run the script in incognito mode of the browser.

How to write test for S3Client with jest?

I am new to Jest and currently practicing writing tests for my old project. I am stuck on how to write a test for Amazon’s S3Client.

const s3 = new S3Client({
  credentials: {
    accessKeyId: bucketAccess,
    secretAccessKey: bucketSecret,
  },
  region: bucketRegion,
});

async function handler ()=>{
   ////

     const commad = new PutObjectCommand(params);
      await s3.send(commad);
}
jest.mock("@aws-sdk/client-s3", () => ({
  PutObjectCommand: jest.fn(),
  S3Client: jest.fn(() => ({
    send: jest.fn(() => "send"),
  })),
}));

describe("upload product", () => {
  it("should send status of 502 on failling on saving img", async () => {
    await uploadProductHandler(mockReq, mockRes);
    const setfail = jest.spyOn(S3Client, "send").mockImplementationOnce(() => Promise.reject("not saved"));
    expect(generateRandom).toHaveBeenCalledTimes(3);
    expect(generateRandom).toHaveBeenLastCalledWith(32);
    expect(PutObjectCommand).toHaveBeenCalledTimes(2);
  });
});

My code is giving error of “Property send does not exist in the provided object”

Can not fetch data from server site after deploying it on vercel

I am zami. Recently I am having problem with a project while fetching data from the server site in the client site. I can easily fetch data in client site when the server site is on localhost but after i deployed the server site on vercel it gives me some errors like cors-policy. the cors middleware is given and i also tried credentials true method. But it did not work. the vercel site link worked but client site can not fetch the data of it and shows cors policy issue. however, using the localhost link of the server site i can easily fetch the data in the client site.
It the problem related to my vercel acciount or projects settings?
i have written many code but it did not work.The link of the backend server deployed by vercel is also good and it worked but the main problem is when i fetch data. And the link given by vercel does not open on firefox it says that i have login tovercel first via firefox as i dont use firefox much it didnot login there.
if you have any opinion about how can i solve this problem please tell me.

i have tried credentials: true in the backend and frontend code to solve this but it did not work

How to create circular carousel with Swiper coverflow

Im not a Swiper expert. I’m using it for the first time, but I’d like to create a circular carousel like the one in the image below.

enter image description here

I found an example but I don’t have an idea about how to edit it and/or if the result I’m looking for can achieved with Swiper:
swiper carousel example

This is the starting point. Any idea about ho to edit this code?

var mySwiper = new Swiper('.swiper-container', {
    loop: true,
    effect: 'coverflow',
    centeredSlides: true,
    slidesPerView: 'auto',

    // Navigation arrows
    navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
    },

})

React component for agSetColumnFilter

I’d like to wrap the standard ag-grid set filter component, so that it works in reverse (it stores the unchecked elements in the model, not the checked ones).

Is it possible to get the react component that corresponds to the name ‘agSetColumnFilter’, and render it in a custom filter component? I would like to not replicate the rendering of checkboxes.

Thank you!

how to create a random algorithm to create an svg image that emulate military mimetic path

I would like to create a military mimetic background SVG image, using an algorithm in JS that generates a random asymmetric geometries.

The goal is to get something like this:
military mimetic pattern

using the basic SVG geometries:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000"
    viewBox="0 0 1000 1000" style="background-color:yellow">
    
    <path d="M 250,500 C 250,500 500,0 750,500 Z" fill="brown">
</svg>

how to access the original nested list after modifying it in loop?

I am modifying the nested list and adding to an array now when I modify nested list it behaving very strangely, I am missing something very small but don’t know what.

class Square {
  constructor() {
    this.value = null;
    this.next = null;
  }
}

let square = new Square();
square.value = [0, 0];

let arrayOfValues = [[1,2], [2, 3], [4, 5]];
let resultArray = [];
arrayOfValues.forEach(v => {
  let copy = square;
  while (copy.next !== null) {
    copy = copy.next;
  }
  let nextNode = new Square()
  nextNode.value = v;
  copy.next = nextNode;
  resultArray.push(square);
})

console.log(resultArray) //[{value: [0, 0], next: {value: [1, 2], next: {value: [2, 3], next: {value: [4, 5], next: null}}}},....]


// want to return [{value: [0, 0], next: {value: [1, 2], next: null}}, ....]

How to load multiple JS Files from Webassembly into one script

I have the problem that I can’t load multiple JS Files from WebAssembly into my Script and work with them.

I am working with WebAssembly and C right now and when I create a JS and a WASM File with emscripten and add it to my script in HTML it all works.

Here is a little code Example that works:

<script src="hello.js"></script>
<script>
    var js_wrapped_fib = Module.cwrap("fib", "number", ["number"]);
    
    function pressBtn(){
        console.log("The result of fib(5) is:", js_wrapped_fib(5));
    }
    </script>
<button onclick="pressBtn()">Click me!</button>

<button onclick=”pressBtn()”>Click me!</button>

But when I add another <script src=””></script> a error comes up, for example here is a not working code:

<script src="hello.js"></script>
<script>
    var js_wrapped_fib = Module.cwrap("fib", "number", ["number"]);
    
    function pressBtn(){
        console.log("The result of fib(5) is:", js_wrapped_fib(5));
    }
    </script>
<button onclick="pressBtn()">Click me!</button>

//Here is the new added code

<script src="hello2.js"></script>
<script>
    var js_wrapped_printout = Module.cwrap("printout", "number", ["number"]);

    function pressBtn2(){
        console.log("The clicked button got the number:", js_wrapped_printout(6));
    }
</script>
<button onclick="pressBtn2()">Click for number</button>

Both work seperatly but not together.

This error comes up when I try to execute it in the console:

1st error: hello2.js:539 Aborted(Module.arguments has been replaced by arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name))

2nd Error: hello2.js:562 Uncaught RuntimeError: Aborted(Module.arguments has been replaced by arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name))
at abort (hello2.js:557:11)
at Object.get (hello.js:801:9)
at hello2.js:216:11

Can somebody please help to load multiple js/wasm scripts in to one html file?

I tried to write a seperate function which loads scripts outside of the html but same error.

I also tried to load multiple non wasm js files into one html file and it worked perfectly so the problem is with the webassembly.

Js code is not fetching form repeater datas

I have a simple html website to make a quotations about tour service.

I have this values

vehicle 1-4 :  - 115
Vehicle 5-12 : 125
...

Guiding 1-4 : 150
Guiding 5-8: 160
...

And a form repeater to add entrances and lunch cost values.

That system makes a calculation like this

(Vehicle price + Guiding price + Common expenses) + (Entrance fees and lunch fees total * number of person)* interest rate.

But when implemented, the form repeater system is not considering form repeater values. What can be the problem?

$(document).ready(function() {
  $('#entranceRepeater').repeater();
  $('#lunchRepeater').repeater();
});

function getRepeaterData(selector) {
  const data = [];
  $(selector).find('[data-repeater-item]').each(function() {
    const name = $(this).find('[name$="Name"]').val();
    const fee = parseFloat($(this).find('[name$="Fee"]').val()) || 0;
    if (name && fee) {
      data.push({
        name,
        fee
      });
    }
  });
  return data;
}

function getVehiclePrice(pax) {
  if (pax <= 4) return parseFloat(document.getElementById('vehicle1').value) || 0;
  if (pax <= 12) return parseFloat(document.getElementById('vehicle2').value) || 0;
  if (pax <= 27) return parseFloat(document.getElementById('vehicle3').value) || 0;
  return parseFloat(document.getElementById('vehicle4').value) || 0;
}

function getGuidePrice(pax) {
  if (pax <= 4) return parseFloat(document.getElementById('guide1').value) || 0;
  if (pax <= 8) return parseFloat(document.getElementById('guide2').value) || 0;
  if (pax <= 12) return parseFloat(document.getElementById('guide3').value) || 0;
  if (pax <= 18) return parseFloat(document.getElementById('guide4').value) || 0;
  if (pax <= 25) return parseFloat(document.getElementById('guide5').value) || 0;
  return parseFloat(document.getElementById('guide6').value) || 0;
}

function calculateCosts() {
  const commonExpenses = parseFloat(document.getElementById('commonExpenses').value) || 0;
  const interestRate = (parseFloat(document.getElementById('interestRate').value) || 0) / 100;
  const maxPeople = parseInt(document.getElementById('maxPeople').value) || 1;

  // Correctly fetch entrance fees and lunch data from repeater
  const entranceData = [];
  $('[data-repeater-list="entranceList"] [data-repeater-item]').each(function() {
    const name = $(this).find('input[name="entranceName"]').val();
    const fee = parseFloat($(this).find('input[name="entranceFee"]').val()) || 0;
    if (name && !isNaN(fee)) {
      entranceData.push({
        name,
        fee
      });
    }
  });

  const lunchData = [];
  $('[data-repeater-list="lunchList"] [data-repeater-item]').each(function() {
    const name = $(this).find('input[name="lunchName"]').val();
    const fee = parseFloat($(this).find('input[name="lunchFee"]').val()) || 0;
    if (name && !isNaN(fee)) {
      lunchData.push({
        name,
        fee
      });
    }
  });

  // Debug logs to verify fetched data
  console.log("Entrance Data:", entranceData);
  console.log("Lunch Data:", lunchData);

  // Sum up entrance and lunch fees
  const totalEntranceFees = entranceData.reduce((sum, item) => sum + item.fee, 0);
  const totalLunchFees = lunchData.reduce((sum, item) => sum + item.fee, 0);

  const resultsContainer = document.getElementById('results');
  resultsContainer.innerHTML = `
                <table>
                    <thead>
                        <tr>
                            <th>Number of People</th>
                            <th>Total Price</th>
                            <th>Price Per Person</th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>
            `;

  const tbody = resultsContainer.querySelector('tbody');
  for (let pax = 1; pax <= maxPeople; pax++) {
    // Determine the appropriate vehicle and guide price based on pax
    const vehiclePrice = getVehiclePrice(pax);
    const guidePrice = getGuidePrice(pax);

    // Calculate total per-person fees for entrance and lunch
    const perPersonCost = (totalEntranceFees + totalLunchFees) * pax;

    // Calculate the total cost including interest
    const totalCost = (vehiclePrice + guidePrice + commonExpenses + perPersonCost) * (1 + interestRate);
    const pricePerPerson = totalCost / pax;

    // Append the results to the table
    const row = document.createElement('tr');
    row.innerHTML = `<td>${pax}</td><td>${totalCost.toFixed(2)}</td><td>${pricePerPerson.toFixed(2)}</td>`;
    tbody.appendChild(row);
  }
}
body {
  font-family: Arial, sans-serif;
  margin: 20px;
}

.section {
  margin-bottom: 20px;
}

input[type="number"],
input[type="text"] {
  width: 100%;
  padding: 5px;
  margin-bottom: 10px;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}

table,
th,
td {
  border: 1px solid #ccc;
}

th,
td {
  padding: 10px;
  text-align: center;
}

.repeater-item {
  margin-bottom: 15px;
  border: 1px solid #ddd;
  padding: 10px;
}

.remove-btn {
  margin-top: 10px;
  color: red;
  cursor: pointer;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.repeater/jquery.repeater.min.js"></script>
<h1>Calculation System</h1>

<!-- Vehicle Prices -->
<div class="section">
  <h2>Vehicle Prices</h2>
  <label>Vehicle for 1-4 Pax:</label>
  <input type="number" id="vehicle1" placeholder="Enter price">
  <label>Vehicle for 5-12 Pax:</label>
  <input type="number" id="vehicle2" placeholder="Enter price">
  <label>Vehicle for 13-27 Pax:</label>
  <input type="number" id="vehicle3" placeholder="Enter price">
  <label>Vehicle for 28-40 Pax:</label>
  <input type="number" id="vehicle4" placeholder="Enter price">
</div>

<!-- Guiding Prices -->
<div class="section">
  <h2>Guiding Prices</h2>
  <label>Guiding for 1-4 Pax:</label>
  <input type="number" id="guide1" placeholder="Enter price">
  <label>Guiding for 5-8 Pax:</label>
  <input type="number" id="guide2" placeholder="Enter price">
  <label>Guiding for 9-12 Pax:</label>
  <input type="number" id="guide3" placeholder="Enter price">
  <label>Guiding for 13-18 Pax:</label>
  <input type="number" id="guide4" placeholder="Enter price">
  <label>Guiding for 19-25 Pax:</label>
  <input type="number" id="guide5" placeholder="Enter price">
  <label>Guiding for 25-40 Pax:</label>
  <input type="number" id="guide6" placeholder="Enter price">
</div>

<!-- Common Expenses -->
<div class="section">
  <h2>Common Expenses</h2>
  <label>Common Expenses:</label>
  <input type="number" id="commonExpenses" placeholder="Enter amount">
</div>

<!-- Entrance and Lunch Items -->
<div class="section">
  <h2>Entrance Places and Lunch Items</h2>
  <div class="repeater" id="entranceRepeater">
    <h3>Entrance Places</h3>
    <div data-repeater-list="entranceList">
      <div data-repeater-item class="repeater-item">
        <label>Entrance Name:</label>
        <input type="text" name="entranceName" placeholder="Enter name">
        <label>Entrance Fee (per person):</label>
        <input type="number" name="entranceFee" placeholder="Enter fee">
        <button data-repeater-delete class="remove-btn">Remove</button>
      </div>
    </div>
    <button data-repeater-create>Add Entrance</button>
  </div>

  <div class="repeater" id="lunchRepeater">
    <h3>Lunch Items</h3>
    <div data-repeater-list="lunchList">
      <div data-repeater-item class="repeater-item">
        <label>Lunch Name:</label>
        <input type="text" name="lunchName" placeholder="Enter name">
        <label>Lunch Fee (per person):</label>
        <input type="number" name="lunchFee" placeholder="Enter fee">
        <button data-repeater-delete class="remove-btn">Remove</button>
      </div>
    </div>
    <button data-repeater-create>Add Lunch</button>
  </div>
</div>

<!-- Interest Rate and People Count -->
<div class="section">
  <h2>Interest Rate and People Count</h2>
  <label>Interest Rate (%):</label>
  <input type="number" id="interestRate" placeholder="Enter percentage">
  <label>Maximum Number of People:</label>
  <input type="number" id="maxPeople" placeholder="Enter maximum number of people">
</div>

<!-- Results -->
<div class="section">
  <button onclick="calculateCosts()">Calculate Costs</button>
  <div id="results"></div>
</div>

Why is this._super undefined the first time Odoo goes into an inherited JS function?

I’m using Odoo 16 and I’m inheriting from a JS function this way:

/** @odoo-module **/
import { StockBarcodeKanbanController } from '@stock_barcode/kanban/stock_barcode_kanban_controller';
import { patch } from 'web.utils';
import { useService } from "@web/core/utils/hooks"; 

patch(StockBarcodeKanbanController.prototype, 'StockBarcodeKanbanControllerIchExt', { 
    setup() {
        this._super.apply(this, arguments);
        this.rpc = useService("rpc");
    },

    async openRecord(record) {
        return this._super.apply(this, arguments);
    },
});

The openRecord function is called when I click on a kanban view card. It opens a special view of stock move lines, that is the original behaviour.

The problem is that the first time I click on the kanban card, a JS error is raised because this._super is undefined. However, if I skip the message and click again on the same kanban card, everything works OK because this._super has the expected value.

Why is this happening and what is the best way to solve it?

So far I did a monkey patch storing the original function in a variable and calling it instead of the super, but I would like to do it well.

Why unused files and folders are created [closed]

https://github.com/victornpb/undiscord
I have a question about the folders and files in that link.
I have one question.

Ultimately, in order to delete messages in Chrome, you only use one file called ‘deleteDiscordMessages.user’.

Question 1: Why are there multiple directories and files other than ‘deleteDiscordMessages.user’? I don’t use them.

Question 2: When I try to code and use it in IDE, an error always occurs. How did you code it? I use vscode.