oidc-client-ts Popup Login Fails with “No window.opener” Error on Callback

Problem Statement

I’m using oidc-client-ts to implement OAuth2 PKCE authentication with a popup login flow. However, when the authentication provider redirects back to my popup callback page, I get the following error (see source code):

No window.opener. Can't complete notification.

What I’m Doing

I initiate the login flow using signinPopup() in my main app:

const userManager = new UserManager({
  authority: "https://your-oidc-provider.com",
  client_id: "your-client-id",
  redirect_uri: window.location.origin + "/callback",
});

async function loginWithPopup() {
  try {
    await userManager.signinPopup();
  } catch (error) {
    console.error("Popup login failed:", error);
  }
}

I handle the popup callback on a separate page (/callback):

const userManager = new UserManager({
  authority: "https://your-oidc-provider.com",
  client_id: "your-client-id",
  redirect_uri: window.location.origin + "/callback",
});

await userManager.signinCallback();

Notes

  • window.opener = null inside the popup console meaning the popup doesn’t recognize the main page
  • window.crossOriginIsolated = false (https://github.com/authts/oidc-client-ts/issues/31#issuecomment-896749759 suggests the popup doesn’t work if it’s true)
  • Note I’m integrating with many different providers so creating a singleton UserManager instance isn’t feasible

What am I doing wrong?

Unable to Extract Data from Dynamically Loaded Content Using Splash

I’m trying to scrape funding opportunity data from https://marie-sklodowska-curie-actions.ec.europa.eu/funding. The data I need includes:

  • Title of the funding opportunity
  • Status (e.g., open, closed)
  • Deadline
  • Link to the opportunity

The website uses dynamic content loading (likely via JavaScript), and I’m using Scrapy with Splash to render the page. However, my current code isn’t extracting any data. Here’s the code I’m using:

import scrapy
from notices.items import MarieCurieItem
from scrapy_splash import SplashRequest

class MscaSpider(scrapy.Spider):
    name = "msca"
    
    def start_requests(self):
        url = 'https://marie-sklodowska-curie-actions.ec.europa.eu/funding'
        yield SplashRequest(url=url, callback=self.parse)

    def parse(self, response):
        msca_item = MarieCurieItem()
        for funding in response.css('article.eac-calls-teaser'):
            msca_item['title'] = funding.css('h3::text').get()
            msca_item['status'] = funding.css('span.deadline-time::text').get()
            msca_item['link'] = funding.css('a::attr(href)').get()
            yield msca_item

Problem:

  1. The response.css selectors aren’t matching any elements, even though the data is visible in the browser.
  2. When I inspect the page, the funding opportunities are loaded dynamically (likely via an API or JavaScript).

What I’ve Tried:

  1. I used Splash to render the page, but the data still isn’t accessible.
  2. I checked the Splash logs and confirmed that the page is loading, but the dynamic content isn’t being captured.

Questions:

  1. How can I modify my Splash script to wait for the dynamic content to load?
  2. Are there better selectors I should use to extract the required data?
  3. Should I directly target the API endpoint instead of rendering the page with Splash? If so, how can I identify the correct API endpoint?

Additional Information:

  • When I inspect the page, the funding opportunities are inside a <eac-faceted-search> component.
  • I tried increasing the wait time in Splash, but it didn’t help.

Any guidance or suggestions would be greatly appreciated!

How to return metadata when using .invoke() and .withStructuredOutput

I’m using LangChain 0.3 (JS/TS) with a gpt-4o model.

const llm = new AzureChatOpenAI({
  azureOpenAIApiDeploymentName: openaiModel,
  temperature: 0,
  maxTokens: undefined,
  timeout: 10 * 60 * 1000,
  maxRetries: 4,
});

const structuredLlm = llm.withStructuredOutput(response_format, { includeRaw: true });
const completion = await structuredLlm.invoke(prompt);
console.log('Completion:', completion);

My problem is that completion only includes the json object the llm has generated. I also would like it to return the request’s metadata, such as the id, number of tokens used, etc.

In the docs I read that adding includeRaw: true should take care of this. But it doesn’t seem to work, as completion still has no metadata inside it. Any idea what I might be doing wrong?

Chrome Extension UserScript Execute Without Refresh Page

Does anyone know a way to make a script registered with chrome.userScript execute immediately without having to refresh the page? In manifest v3 the accepted way to execute user script is through the userScript API. But when a script is registered with this API it only actually executes when the page is reloaded.

I am trying to render a video to my react native mobile app but it come up as blank

const renderPost = ({ item }) => {
const mediaUri = http://10.50.99.238:5001${item.media_url};

return (
  <View
    style={{ padding: 10, borderBottomWidth: 1, borderBottomColor: "#ccc" }}
  >
    <Text style={{ fontWeight: "bold" }}>{item.user_id}</Text>
    {item.media_url &&
    item.media_url.endsWith(".mp4") &&
    isValidUrl(mediaUri) ? (
      <View style={{ width: "100%", height: 200 }}>
        <VideoView
          source={{ uri: mediaUri }}
          style={{ width: "100%", height: 300 }}
          useNativeControls // Use native controls for play/pause etc.
          resizeMode="contain"
          shouldPlay // Start playing as soon as it's loaded
          isLooping // Loop the video
          onError={(error) => console.log("Video Error:", error)}
          onLoadStart={() => console.log("Loading video...")}
          onLoad={() => console.log("Video loaded successfully")}
        />
      </View>
    ) : item.media_url && isValidUrl(mediaUri) ? (
      <Image
        source={{ uri: mediaUri }}
        style={{ width: "100%", height: 200, marginVertical: 10 }}
        resizeMode="contain"
      />
    ) : (
      <Text>Invalid media URL</Text>
    )}
    <Text>{item.caption}</Text>
  </View>
);

};

I am new to react native development and trying to render video on my React native app, the video uri is coming from my nodeJs backend which stores the media files in /uploads folder using multer. While the images are shown the video does not show, it just shows a blank space. Please help, thanks in advance

Issue converting Byte Array PDF from backend server to frontend JS blob

I have a frontend/backend working, but struggling to get the backend to grab a PDF, turn it into an array of bytes, send it to the front end, and have the front end transform it into a blob, and display the working PDF on the front end display. Currently, the error I am getting is that its displaying on the front end as “Error , failed to load PDF document” and not giving much other error info. So its sending the info, but maybe not formatting correctly?

Image of error

I took out some info that I cannot show (what Item is, or how the Item is used on the backend to grab the correct pdf, sorry)

Backend :

[Route("grab-pdf")]
[ApiController]

public async Task <ActionResult> Create(request) {
byte[] pdf = system.IO.File.ReadAllByters("fileexample.pdf");
return File()pdf, "application/pdf","pdfexampletitle");
}

frontend :

var items = [{ id: "1", amount : 100}]

grabPDF(); 

async function grabPDF() { 
const response = await fetch("/grab-pdf", {
method : "POST",
headers : {"Content-Type": "application/json"},
body : JSON.stringify ({items}),
}); 

const {invAmt}  = await response.blob();
//const blob = new blob([(response.blob()], { type: 'application/pdf' });  //I tried using this, but gave same error
const url = URL.createObjectURL(invAmt);
const iframe = document.createElement("iframe");
iframe.src = url
iframe.style.width = '100%';
iframe.style.height = '900px';
document.body.appendChild(iframe);

}

Making a “window” through which part of the element is visible

I'm trying to make a login/register page in a slightly unusual way, but I can't figure out how to set up the styles.
I'm using vue3, but I don't think it matters here.

The idea is to have two "windows" visible on the main element (let's say, body ), through which a part of the login page and register page is visible. And when hovered over, this window should expand to full screen, exposing the component that was hidden under the window.
There are a couple of pictures at the end of the message, that can help you to understand me.

However, I can't implement this either with clip-path or with overflow:hidden.

When using overflow, the child element (login page) is positioned relative to the wrapper (the wrapper is the "window" through which a piece of the login page is visible), and I can't position the "window" normally so that only the "login" button is visible through it, and so that it expands normally.

And when using clip-path, the element is cut off so that it cannot be customized - add a border or something else.

I also tried to use a mask, but also failed.

In general, I came up with a task for myself and I can’t figure out how to implement such, at first glance, simple functionality.

I hope someone can help, because chat-gpt is not ready to solve such a problem, and does not even understand what I want from it :(
here some images that can help understand what i imagine
[img1](https://i.sstatic.net/GPuXelzQ.jpg)
[img2](https://i.sstatic.net/JpVfnlJ2.jpg)
[img3](https://i.sstatic.net/WieVikCw.jpg)

i tried iafhbidfb bhfasduofuaf so hard aosjdnipasndkasnd asda sd asd sa vgasd gasdgasdg asd gasd g asdg sadg sad g
asdasdas
asdasdasd

Animate transform-origin while maintaining previous rotation position

I am trying to animate a “left” to “right”-side rotation using transform-origin. More specifically, I would like to maintain the left side’s rotation position when the transform-origin is switched. Is there a way for me to preserve this positioning despite the rotation being relative to the current origin?

For example,
(1) when left is executed -> [].
(2) when right is executed -> [-], while maintaining left side previous position.

function rotate(direction) {
  const rotatedBox = document.getElementsByClassName("rotatedBox")[0]
  if (direction === "right") {
    rotatedBox.classList.remove("left")
    rotatedBox.classList.add("right")
  } else if (direction === "left") {
    rotatedBox.classList.remove("right")
    rotatedBox.classList.add("left")
  }
}
.bigBox {
  border: solid 1px red;
  height: 80vh;
  width: 70vw;
  position: relative;
}

.rotatedBox {
  border: solid 1px greenyellow;
  background-color: teal;
  height: 10px;
  position: absolute;
  bottom: 0;
  width: 100%;
  transition: transform-origin 0.2s ease-in-out;
}

.rotatedBox.right {
  transform-origin: 0% 50% 0px;
  transform: rotate(-10deg);
}

.rotatedBox.left {
  transform-origin: 100% 50% 0px;
  transform: rotate(10deg);
}
<button onclick="rotate('left')">left</button>
<button onclick="rotate('right')">right</button>
<div class="bigBox">
  <div class="rotatedBox"></div>
</div>

Error to create a carousel with a pure-react-carousel

may you help me? I’m trying to create a carousel with pure-react-carousel but I’m getting the error: RangeError: Maximum call stack size exceeded
Below is the MRE:

Index:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>

React Component

import React from 'react';
import { CarouselProvider, Slider, Slide, ButtonBack, ButtonNext } from 'pure-react-carousel';
import 'pure-react-carousel/dist/react-carousel.es.css';

const CarouselTest = () => {
    return (
        <CarouselProvider
            visibleSlides={1}
            step={1}
            totalSlides={3}
            isIntrinsicHeight={true}
        >
            <Slider>
                <Slide index={0}>First Slide</Slide>
                <Slide index={1}>Second Slide</Slide>
                <Slide index={2}>Third Slide</Slide>
            </Slider>
            <ButtonBack>Anterior</ButtonBack>
            <ButtonNext>Próximo</ButtonNext>
        </CarouselProvider>
    );
};

export default CarouselTest;

The error seems to be related to an infinite loop, but I can’t find the reason.

An error occurred in the component.

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://react.dev/link/error-boundaries to learn more about error boundaries.

Google Apps Script Web App Not Working When Embedded on Namecheap Website

Google Apps Script Web App Not Working When Embedded on Namecheap Website

Problem Overview

I’m trying to create an order tracking feature on my Namecheap-hosted website that searches a Google Sheet when a user inputs an order number and returns the corresponding information.

What Works

  • The Apps Script web app functions correctly when accessed directly via its URL in Safari
  • The search functionality works as expected when I open the html file, containing the apps script url, on safari.

What Doesn’t Work

  • When embedded on my Namecheap website, the JavaScript appears to be treated as a string rather than being executed
  • When I try to embed just the Apps Script link on Namecheap, I get a 403 error from Google (“You need access”)

What I’ve Tried

I’ve attempted several variations of my doGet() function to resolve CORS/access issues:

Variation 1: JSONP with CORS headers

function doGet(e) {
  const orderNumber = e.parameter.orderNumber;
  const callback = e.parameter.callback || 'callback'; // Default callback name if none provided
  
  if (!orderNumber) {
    return ContentService.createTextOutput(callback + '(' + JSON.stringify({ success: false, message: "No order number provided" }) + ')')
      .setMimeType(ContentService.MimeType.JAVASCRIPT); // Returns JavaScript JSONP format
  }
  
  const result = searchOrder(orderNumber);
  
  const output = ContentService.createTextOutput(callback + '(' + JSON.stringify(result) + ')')
    .setMimeType(ContentService.MimeType.JAVASCRIPT);
  output.setHeader("Access-Control-Allow-Origin", "*");
  output.setHeader("Access-Control-Allow-Methods", "GET, POST");
  output.setHeader("Access-Control-Allow-Headers", "Content-Type");
  
  return output;
}

Variation 2: Pure JSONP approach

function doGet(e) {
  // Get the order number and callback from the request parameters
  const orderNumber = e.parameter.orderNumber;
  const callback = e.parameter.callback || 'callback'; // Default callback if none provided
  
  // If no order number was provided, return an error
  if (!orderNumber) {
    return ContentService.createTextOutput(callback + '(' + JSON.stringify({ success: false, message: "No order number provided" }) + ')')
      .setMimeType(ContentService.MimeType.JAVASCRIPT); // Returns JavaScript JSONP format
  }
  
  // Search for the order
  const result = searchOrder(orderNumber);
  
  // Return the result as JSONP - this format allows cross-domain requests
  // by wrapping the JSON in a function call that will be executed by the browser
  return ContentService.createTextOutput(callback + '(' + JSON.stringify(result) + ')')
    .setMimeType(ContentService.MimeType.JAVASCRIPT);
}

Variation 3: Pure JSON approach (no JSONP, no callback)

function doGet(e) {
  // Get the order number from the request parameters
  const orderNumber = e.parameter.orderNumber;
  
  // If no order number was provided, return an error
  if (!orderNumber) {
    return ContentService.createTextOutput(JSON.stringify({ success: false, message: "No order number provided" }))
      .setMimeType(ContentService.MimeType.JSON); // Returns plain JSON format
  }
  
  // Search for the order
  const result = searchOrder(orderNumber);
  
  // Return the result as pure JSON (no callback wrapping)
  return ContentService.createTextOutput(JSON.stringify(result))
    .setMimeType(ContentService.MimeType.JSON);
}

Deployment Settings

  • Script is deployed as a web app executing as me
  • Access is set to “Anyone”
  • I’ve even tried changing the Google Spreadsheet access to “Anyone” but that didn’t resolve the issue

Other Information

  • Namecheap support suggested that I need to whitelist my server IP, but I was under the impression this isn’t possible with Google Apps Script

Question

How can I successfully integrate my Google Apps Script web app with my Namecheap website to enable the order tracking functionality? Is there a way to resolve the 403 access error or prevent the JavaScript from being treated as a string?

Why doesn’t this object compile in Typescript? [duplicate]

In Javascript the following compiles (I’m particularly referring to the function as the key):

const object = {
  key: 1,
  "key key": 2,
  3: 3,
  [() => undefined]: 4,
};

console.log(Object.keys(object));

Link

My understanding is that is that the function signature will be (like any other key, correct me if I’m wrong) be converted into a string. But it does not compile in Typescript:

It gives error:

A computed property name must be of type ‘string’, ‘number’, ‘symbol’,
or ‘any’.