Why does my website keep redirecting me to the spotify authentication page?

Im using the spotify PKCE authentication for my website. However, no matter if I press agree or cancel, it just keeps redirecting back to the authentication page. I am trying to make a website that will recommend music based on certain criteria and play said music, should I even be using the PKCE authentication or a different one? I’m very new to this stuff.

const clientId = '';
const code = undefined;
if (!code) {
  redirectToAuthCodeFlow(clientId);
} else {
  const accessToken =  getAccessToken(clientId, code);
  const profile =  fetchProfile(accessToken);
  populateUI(profile);
}

async function redirectToAuthCodeFlow(clientId) {
  // TODO: Redirect to Spotify authorization page
  const verifier = generateCodeVerifier(128);
  const challenge = await generateCodeChallenge(verifier);

  localStorage.setItem("verifier", verifier);

  const params = new URLSearchParams();
  params.append("client_id", clientId);
  params.append("response_type", "code");
  params.append("redirect_uri", "http://127.0.0.1:3000/index.html");
  params.append("scope", "user-read-private user-read-email");
  params.append("code_challenge_method", "S256");
  params.append("code_challenge", challenge);

  document.location = `https://accounts.spotify.com/authorize?${params.toString()}`;
}

function generateCodeVerifier(length) {
  let text = '';
  let possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

  for (let i = 0; i < length; i++) {
      text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
}

async function generateCodeChallenge(codeVerifier) {
  const data = new TextEncoder().encode(codeVerifier);
  const digest = await window.crypto.subtle.digest('SHA-256', data);
  return btoa(String.fromCharCode.apply(null, [...new Uint8Array(digest)]))
      .replace(/+/g, '-')
      .replace(///g, '_')
      .replace(/=+$/, '');
}


async function getAccessToken(clientId, code) {
  // TODO: Get access token for code
  const verifier = localStorage.getItem("verifier");

    const params = new URLSearchParams();
    params.append("client_id", clientId);
    params.append("grant_type", "authorization_code");
    params.append("code", code);
    params.append("redirect_uri", "http://localhost:5173/callback");
    params.append("code_verifier", verifier);

    const result = await fetch("https://accounts.spotify.com/api/token", {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        body: params
    });

    const { access_token } = await result.json();
    return access_token;
    console.log(access_token);

}

Most of the code is copied from spotify’s website.

Read or count pages of a digital signed pdf document using php or javascript

I am trying to read a pdf which is digitally signed. I tried using different php libraries and also js libraries, each of them works well with a normal pdf document but if the document is digitally signed then it cant read it. Tried libraries mpdf, setassign/fpdi etc. I even tried to remove the digital signature and make a copy of it and then count the pages of the document using ghostscript but not working, but it can’t remove the sign, Is there any way around to do it ? any idea would be appreciated.

How to make trigger change work in Select2?

There is a piece of code that is responsible for updating the QR code during events [‘paste’, ‘keyup’, ‘change’], but for some reason the Select2 list does not work and accordingly, does not transmit data.

my part of code

let apply_reload_qr_code_event_listeners = () => {
        document.querySelectorAll('[data-reload-qr-code]').forEach(element => {
            let events = ['paste', 'keyup', 'change'];
            events.forEach(event_type => {
                element.removeEventListener(event_type, reload_qr_code_event_listener);
                element.addEventListener(event_type, reload_qr_code_event_listener);
            })
        });
    }

Even though data-reload-qr-code is added to input Select2, it does not work, but all other fields work without problems.

How to stop page theme FLASH in Next.JS 15 using Tailwind CSS and prevent hydration mismatch

Is it possible to implement a successful page theme initialisation without the common flash issue, and whilst also avoiding any hydration mismatch errors?

My solution so far has been to execute JavaScript before the full page renders, by using <script> in the <head> tag, to check the users localStorage, and then apply the theme.

This works perfectly, except I am getting a hydration error in the console. This is obviously because the localStorage can only be checked on the client side, so the server-rendered HTML and client-rendered HTML never match.

I’d just ignore this console error, but isn’t it true that a hydration mismatch indicates that React had to discard the server-rendered HTML and re-render the tree on the client? I’m not particularly happy with having to accept that for concern of performance degradation.

The only other solution there seems to be from my research is either to pass the users selected theme through cookies, which I’d rather less prefer as localStorage is more persistent – or to save the users preference server side, which seems a bit unnecessary all for the sake of avoiding a half second flash.

Is there really no way to do this using localStorage? My main question is more focused on avoiding this hydration issue. I’ve already got a solution that works, but I don’t want to avoid the hydration mismatch. The best I can come up with is setting a default Tailwind theme class such as light to the <html> tag. This way, I can eliminate half the issue by assuring the hydration error only occurs if the theme is dark, rather than there always being a mismatch. Would like to get the other half, but can’t logically think how to do it. Maybe there is some clever way?

Code below:

import type { Metadata } from "next";
import "./globals.css";
import NavBar from "./components/NavBar/NavBar";
import Footer from "./components/Footer/Footer";

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const initTheme = `
  (function() {
    const theme = localStorage.getItem("theme") || "light";
    document.documentElement.classList.remove('light', 'dark');
    document.documentElement.classList.add(theme);})();
  `;
  return (
    <html lang="en" className="light">
      <head>
        <link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
        <script dangerouslySetInnerHTML={{ __html: initTheme }} />
      </head>
      <body>
        <NavBar></NavBar>
        {children}
        <Footer></Footer>
      </body>
    </html>
  );
}

Javascript class, initialize with object & optional values

I have a few questions regarding the code below:

export class Person {
    constructor(obj = { id: 0, name: '', lastName: '', eyeColor: '', age: 0 }) {
        this.id = obj.id;
        this.name = obj.name;
        this.lastName = obj.lastName;
        this.eyeColor = obj.eyeColor;
        this.age = obj.age;
    }

    yearOfBirth() {
        return new Date().getFullYear() - this.age;
    }

    json() {
        return JSON.stringify(this);
    }
}

FWIW: I prefer to create an object using this syntax:

let newPerson = new Person(
  { 
    id: 0, 
    name: "Werner", 
    lastName: "Venter", 
    age: 37
  }
);

I really dislike this way:

let newPerson = new Person(0, "Werner", "Venter", 37);

It just reads easier for me when I have the parameter name with the value. Anyway, I digress…

  1. Is this the correct/accepted way to create an object class? I will be using it to receive data from an API that sends it in this format as JSON.
  2. How do I make a parameter optional? Mainly why I need this is that the ID value is not required when creating a new entry on the API, so I would prefer not to include the ID value when creating the object.
  3. Finally, do you have any opinion/advice on this approach?

Thank you in advance guys. Really appreciate this community.

Referencing Json files in Storyline 360

Storyline gives advice on how to add external Javascript to a course:
https://access.articulate.com/support/article/Articulate-Storyline-360-JavaScript-Best-Practices-and-Examples

By adding the following to the story.html file:

<script LANGUAGE="JavaScript1.2" SRC="/story_content/MyJavaScriptFunctions.js" TYPE="text/javascript"></script>

And then inserting the .js file into the story_content folder.

Is there a way to insert a .json file into story_content and have javascript reference it?

Error [ERR_REQUIRE_CYCLE_MODULE]: Cannot require() ES Module…but I’m not

Trying to run my node app, with node main.js, but getting this error: Error [ERR_REQUIRE_CYCLE_MODULE]: Cannot require() ES Module. I have also tried node --experimental-specifier-resolution=node main.js.

My main.js file imports things from './schema/index.js' using regular esm syntax, like: import { importName } from './schema/index.js'. I am not using require, so not sure why it’s accusing me of that.

Full error shown below.

What am I doing wrong here?

→ node main.js
node:internal/modules/esm/loader:315
        throw new ERR_REQUIRE_CYCLE_MODULE(message);
              ^

Error [ERR_REQUIRE_CYCLE_MODULE]: Cannot require() ES Module /path/to/app/schema/index.js in a cycle. (from /path/to/app/noop.js)
    at ModuleLoader.importSyncForRequire (node:internal/modules/esm/loader:315:15)
    at loadESMFromCJS (node:internal/modules/cjs/loader:1414:24)
    at Module._compile (node:internal/modules/cjs/loader:1547:5)
    at Object..js (node:internal/modules/cjs/loader:1677:16)
    at Module.load (node:internal/modules/cjs/loader:1318:32)
    at Function._load (node:internal/modules/cjs/loader:1128:12)
    at TracingChannel.traceSync (node:diagnostics_channel:322:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:219:24)
    at Module.require (node:internal/modules/cjs/loader:1340:12)
    at require (node:internal/modules/helpers:138:16) {
  code: 'ERR_REQUIRE_CYCLE_MODULE'
}

Node.js v22.12.0

PS. There is no file called noop.js, and I have no idea what that part means!! Has anyone seen this before?

package.json:

{
  "name": "writing-api-subgraph-storybook",
  "version": "0.0.1",
  "dependencies": {},
  "packageManager": "[email protected]",
  "module": "./main.js",
  "type": "module",
  "main": "./main.js"
}

How do you pass a bound method as a parameter in javascript?

I’m trying to pass a bound method to a function, but I can’t quite figure out the syntax. It seems like javascript wants to somehow differentiate between an unbound method and a bound method, but where the calling context changes that. (Most programming languages simply define a method as a bound class function).

What’s the syntax for passing a bound method to a function, and then calling that bound method in the new scope?

Here’s the relevant snippets

const mongoose = require('mongoose');
const caching = require('../lib/caching')

const Blog = mongoose.model('Blog');

// This is where I'm trying to pass a method to another function. I'm unclear of the syntax here
Blog.find = caching.makeCachable(Blog.find.bind(Blog), Blog)

module.exports = app => {
  app.get('/api/blogs', requireLogin, async (req, res) => {
    let blogs = await Blog.find({_user: req.user.id});
    return res.send(blogs);
  });

  // ... other routes
}

caching.js

const util = require('util');
const redis = require('redis');

const client = redis.createClient('redis://localhost:6379');
const asyncGet = util.promisify(client.get).bind(client);

const DEFAULT_CACHING = [
    'EX', 60 * 60 * 1,//caching expires after 4 hours
]

// This is where I take the method and pass it on to another function. I hope this just passes through
function makeCachable(method, thisObject) {
    console.log(method, thisObject, `${method.className}.${method.name}`);
    return cachedQuery.bind(method, `${thisObject.className}.${method.name}`);
}

async function cachedQuery(queryFunction, queryKey, queryParams=null, cacheConfig=DEFAULT_CACHING) {
    //check redis before executing queryFunction
    const redisKey = JSON.stringify([queryKey, queryParams]);
    const cacheValue = await asyncGet(redisKey);

    if(cacheValue) {
        return JSON.parse(cacheValue);
    }
    
    // This is where I try to call the bound method
    const blogs = await queryFunction.call(queryParams);
    
    if(blogs) {
        client.set(redisKey, JSON.stringify(blogs), ...cacheConfig);
    }

    return blogs;
}

exports.makeCachable = makeCachable;

Combine data from different cells in a table

I’m trying to read data stored in a csv file and present it in a table, using JavaScript. The csv data (comma delimited) is (I reduced it to be much smaller than the actual one):

Number, PDF1, PDF2, PDF3
0,,,
1,1.pdf,,
2,2a.pdf,2b.pdf,
3,3a.pdf,3b.pdf,3c.pdf

The correspondence between cells in the csv and online is 1 to 1, except 3 last columns (PDF1/2/3). I need them to appear online in the same cell (for each row) as links, separated by space. That is, instead of 3 columns PDF1/2/3 there will be just one, called PDF, containing links to pdfs 1, 2 and 3, if present. The desired output is:

| Number | PDF                                      |
| 0      |                                          |
| 1      | [link>1.pdf]                             |
| 2      | [link>2a.pdf] [link>2b.pdf]              |
| 3      | [link>3a.pdf] [link>3b.pdf] [link>3c.pdf]|

What I have so far:

html:

<span id="output"></span>

JS:

async function fetchCSV(url) {
    try {
        const response = await fetch(url);
        const data = await response.text();
        document.getElementById('output').innerText = data;
        processData(data);
    } catch (error) {
        console.error('Error fetching CSV:', error);
    }
}

//Link to csv file
fetchCSV('https://blabla/myfile.csv');

//read csv and save contents to variable "lines"
function processData(csv){
    var allTextLines = csv.split(/rn|n/);
    var lines = [];
    var keys = allTextLines.shift().split(','); //first line (headers) of csv
    while (allTextLines.length) {
        var arr = allTextLines.shift().split(',');
        var obj = {};
        for(var i = 0; i < keys.length; i++){
            obj[keys[i]] = arr[i];
    }
        lines.push(obj);
    }
    console.log(lines);
    drawOutput(lines);
}

//draw table function drawOutput(lines){
    //clear previous data
    document.getElementById("output").innerHTML = "";
    var table = document.createElement("table");

//first row (cols names) with "th"
var tableHeader = table.insertRow(-1);
Object.keys(lines[0]).forEach(function(key){
    if (key == "PDF1") {} //don't show "PDF1" column
    else if (key == "PDF2") {} //don't show "PDF2" column
    else {
        var el = document.createElement("TH");
        if (key == "PDF3") {el.innerHTML = "PDF";} //show "PDF3" column as "PDF"
        else {el.innerHTML = key;}
        tableHeader.appendChild(el);
    }
});

//the data (rest of the table)
for (var i = 0; i < lines.length-1; i++) {
    var row = table.insertRow(-1);
    Object.keys(lines[0]).forEach(function(key){
      if (key == "PDF1") {var pdflink1 = lines[i][key];}
      else if (key == "PDF2") {var pdflink2 = lines[i][key];}
      else if (key == "PDF3") {var pdflink3 = lines[i][key];
          var data = row.insertCell(-1);
          if (pdflink1 != []) {
              var a1 = document.createElement('a');
              a1.innerHTML = 'pdf1 ';
              a1.href = "dir/" + pdflink1;
              data.appendChild(a1);
          }
          if (pdflink2 != []) {
              var a2 = document.createElement('a');
              a2.innerHTML = 'pdf2 ';
              a2.href = "dir/" + pdflink2;
              data.appendChild(a2);
          }
          if (pdflink3 != []) {
              var a3 = document.createElement('a');
              a3.innerHTML = 'pdf3';
              a3.href = "dir/" + pdflink3;
              data.appendChild(a3);}
          }
      else {
    var data = row.insertCell(-1);
    data.appendChild(document.createTextNode(lines[i][key]));
  }});
}
document.getElementById("output").appendChild(table);
}

Everything seems to work OK, but I’m struggling to “keep” the pdf names in pdflink1 and pdflink2 to put them together with pdflink3 when key == “PDF3” is true. Out of three, only the latter is presented as desired in the output:

| Number | PDF                                         |
| 0      |                                             |
| 1      | [dir/undefined]                             |
| 2      | [dir/undefined] [dir/undefined]             |
| 3      | [dir/undefined] [dir/undefined] [dir/3c.pdf]|

I appreciate any assistance. Thank you.

JS, Is there a way web client access file cached date of image url?

I have a react component for thumbnails in client,

export default function Thumbnail({
  url,
  updatedDate, // updatedDate is from server api
}) {
  const cachedDate = new Date(.....);
  const queryStr = cachedDate < updatedDate ? '?force=' + Math.random() : '';

  return (
    <img
      src={url + queryStr}
      alt={'THUMB'}
    />

)}

How can I get cachedDate? Is it possible?

mouse drag function in javascript

I am not familiar with javascript coding to deal with the problem of the source code on my own.
I downloaded a nice Linkage Simulator code written in Javascript from this website https://edu-mat.sakuraweb.com/linksim/index_en.html. Please go down to Download and click on icon download system. You will get linksys_1.01.zip file. Unzip it to get javascript code on your computer.
The problem is dragging the parts on the screen. When I run Linksys from their website, the dragging of the mechanical parts on the screen with you mouse icon works fine.
When I run javascript code from my PC, the code runs fine except when I try drag mechanical parts with my mouse. The parts are stuck. Obviously, the mouse function for dragging the parts is disabled. How do I enable it?
Thank you for your time.

Problems with some glowing style on safari

Im having trouble with safari, that makes me that square effect, I don’t remember how to fix it!

const getGlowingStyles = (theme: Theme) => {
  const glowing = keyframes`
    0% { background-position: 0 0; }
     50% { background-position: 400% 0; }
    100% { background-position: 0 0; }
  `

  const glowingStyles = {
    position: 'absolute',
    right: '0px',
    bottom: '0px',
    background: `linear-gradient(45deg, ${theme.palette.accent.light}, ${theme.palette.accent.main}, ${theme.palette.accent.main}, ${theme.palette.accent.main}, ${theme.palette.accent.light}, ${theme.palette.accent.main}, ${theme.palette.accent.light}, ${theme.palette.accent.main})`,
    backgroundSize: '800%',
    borderRadius: '50%',
    filter: 'blur(8px)',
    animation: `${glowing} 15s linear infinite`,
    zIndex: -1,
    overflow: 'hidden'
  }
  return glowingStyles
}

<Box
  sx={{
    width: 115,
    height: 115,
    top: '25px',
    left: '25px',
    ...getGlowingStyles(theme)
  }}
/>

Safari’s view:

enter image description here

Chrome’s view:

enter image description here

Run Cypress 13 on a machine without Internet connection

We would like to run Cypress tests on a machine that has no connection to the Internet. The machine runs an Ubuntu 22.04.5LTS operating system.

Steps to reproduce:

On an Ubuntu machine with Internet access:

  • Run “npm install cypress –save-dev” to install cypress (current version 13.17.0) on the machine.

  • Run “npx cypress open”: Cypress app can be opened

  • Copy the parent folder where npm install was executed and the Cypress cache under “~/.cache/Cypress/13.17.0” to a similar Ubuntu machine without internet access. It was placed under the same folder structure on the target machine.

On the Ubuntu machine without Internet access:

  • Run “npx cypress open”: Cypress app starts up but is stuck on the first loading screen (see image: Cypress loading screen)

Is there any way to open/run Cypress (13.17.0) without any connection to the Internet? Are we missing any files required to open Cypress?

getComputedStyle wrong for placeholder on some mobile devices

This seems like a browser bug to me but I couldn’t find anyone else seeing the same problem. It seems like getComputedStyle isn’t getting the right font-size for an input placeholder for some mobile browsers.

In my example below the placeholder font-size is set to 11px. In some mobile browsers, getComputedStyle thinks the placeholder’s font size is 16px.

I’ve tested this on:

  • iPhone 16 in Safari and Chrome: 16px

  • Samsung Galaxy S22 in Chrome: 16px

  • Samsung Galaxy S22 in Firefox: 11px

  • Chrome and Firefox on Win11: 11px

See this jsfiddle, or snippet below:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css">
<style>
.form-control::placeholder {
  font-size: 11px;
}
</style>

<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<script>
function updatePlaceholderLength(el) {
    var styles = window.getComputedStyle(el);
    var placeholderFontSize = window.getComputedStyle(el, '::placeholder').fontSize;
    
   document.querySelector('.debug-info-js').textContent = 'placeholder font size: ' + placeholderFontSize;
}

updatePlaceholderLength(document.getElementById('whatever'));
</script>

<div class="container">
  <label class="control-label" for="whatever">Check it out</label>
  <input class="form-control" id="whatever" type="text" placeholder="Here is my placeholder.">
  <hr>
  <pre class="debug-info-js"></pre>
</div>

Just wondering if anyone has any info on this… is it a known bug/limitation? Is this by design? Is there any workaround to get the right font-size?

Tried adding !important to the font-size declaration which of course didn’t work… I have no idea what else I can do.

Arabic “Majed” voice randomly not showing in SpeechSynthesis (TTS) API

Browsers with the SpeechSynthesis provide Arabic through one voice “Majed” as ar-001 or ar-SA and it usually works on all browsers except ones that use WebKit I noticed.
On Webkit based browsers, especially iPhones & iPads, that specific voice doesn’t appear randomly sometimes! I am trying to figure out how can I make sure that an Arabic language can always be used?

Here’s a codepen where you can try it yourself. For the SAME device, when I go to that page the first time, Majed appears, but it didn’t appear a few times later. You can also just open a developer console on any page and put in window.speechSynthesis.getVoices() and the first element in the list should be arabic (majed)

This is what it looks like on a Mac using Safari sometimes, where Arabic does appear above Daria as it does appear correctly with other browsers and operating systems
Screenshot showing Arabic
This is what it looks like on an iPhone/iPad sometimes, where the Arabic doesn’t appear at all when it should appear above “Daria”:
Screenshot from iPhone not showing Arabic