Trying to use login-2FA and i am getting this error, Failed to load resource: the server responded with a status of 401 ()

Invalid OTP error when using front end, when I test API with swagger it works fine.

I am trying to implement asp.net 2FA authentication but i am getting error Invalid OTP when i try to use the front end, even though I received the email with the OTP. When i test the API using swagger i am able to get the JWT token and login.

OTPVerification.jsx

    function OTPVerification({ isOpen, onOpenChange, username, length = 6 }) {
    const { setIsLoading, isLoading, verifyOTP } = useAuth();

    const handleOtpSubmit = async (otp) => {
        setIsLoading(true);

        try {

            if (otp.length !== 6 || isNaN(otp)) {
                toast.error('Please enter a valid 6-digit OTP.');
                return;
            }
            console.log("Username: ", username);
            console.log("OTP: ", otp);
            const response = await verifyOTP(username,otp);
            console.log("Response: ", response);
            if (response.success) {
                toast.success('OTP Verified Successfully!');
                onOpenChange(false);
            } else {
                toast.error(response.message || 'OTP Verification Failed. Please try again.');
            }
        } catch (error) {
            console.error('Error during OTP verification:', error);
            const message = error.response?.data?.message || 'An error occurred during OTP      verification. Please try again.';
            toast.error(message);
        } finally {
            setIsLoading(false);
        }
    };

AuthContext,jsx

    async function verifyOTP(username, otp) {
    setIsLoading(true); // Start loading state
   
    try {
        const response = await axios.post('/api/Auth/login-2FA', {
            Username: username,
            OTP: otp
        });

        console.log('Sent OTP request:', { username, otp });

        if (response.data.Status === 'Success') {
            login(response.data.token, response.data.user);
            return { success: true, token: response.data.token, user: response.data.user };
        } else {
            return { success: false, message: response.data.Message };
        }
    } catch (error) {
        console.error('Error verifying OTP:', error);
        const message = error.response?.data?.message || 'An error occurred. Please try again.';
        return { success: false, message };
    } finally {
        setIsLoading(false); // Stop loading state
    }
}

AuthController.cs

    [HttpPost]
[Route("login-2FA")]
public async Task<IActionResult> LoginWithOTP([FromBody] OtpRequest request)
{
    // Validate the request
    if (request == null || string.IsNullOrEmpty(request.OTP) || string.IsNullOrEmpty(request.Username))
    {
        _logger.LogWarning("Invalid OTP request: Missing code or username.");
        return BadRequest(new { Status = "Error", Message = "Code and Username are required." });
    }

    // Find the user by username
    var user = await _userManager.FindByNameAsync(request.Username.ToLower());
    if (user == null)
    {
        _logger.LogWarning("OTP login attempt for non-existent user: {Username}", request.Username);
        return Unauthorized(new { Status = "Error", Message = "Invalid username or OTP ." });
    }
    if (await _userManager.IsLockedOutAsync(user))
    {
        _logger.LogWarning("User is locked out: {Username}", user.UserName);
        return Unauthorized(new { Status = "Error", Message = "User account is locked out." });
    }

    // Verify the OTP token
    var signInResult = await _signInManager.TwoFactorSignInAsync("Email", request.OTP, rememberClient: false, isPersistent: false);

        if (signInResult.Succeeded)
        {
        // Generate JWT token
        var authClaims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };

        // Add user roles to claims
        var userRoles = await _userManager.GetRolesAsync(user);
        foreach (var role in userRoles)
        {
            authClaims.Add(new Claim(ClaimTypes.Role, role));
        }

        // Generate token string using claims
        var jwtToken = GenerateTokenString(authClaims);

        _logger.LogInformation("2FA login successful for user: {Username}", user.UserName);

        return Ok(new
        {
            token = jwtToken,
            expiration = new JwtSecurityTokenHandler().ReadJwtToken(jwtToken).ValidTo
        });
    }

    _logger.LogWarning("Invalid OTP provided for user: {Username}.", request.Username);
    return Unauthorized(new { Status = "Error", Message = "Invalid OTP." });
}

Why my 3d model keeps placing text not in the middle of y coordinates but a little below it?

I’ve spent two days going back and forth, and it’s still the same. The text engraving depth varies on my curved 3D ring model—one side of the letter is deep, while the other side is not. I’m trying to use my .glb ring model, change its texture to silver, and add text that appears in the middle and looks engraved. I also want to be able to use x and y sliders to move the text. I could really use some help with this.

Main problem is: 1. wrong text alignment after i input text (its not in the middle of y axis.
2. Text looks not evenly deep.

{% assign model_found = false %} 

{% for media in product.media %}
  {% if media.media_type == 'model' %}
    {% assign model_url = media.sources[0].url %}
    
    <!-- 3D Model Container -->
    <div id="3d-container" style="width: 100%; height: 0; padding-bottom: 75%; position: relative;"></div>

    <!-- Text Input for Engraving -->
    <div style="margin-top: 20px; text-align: center;">
      <input type="text" id="engraveText" placeholder="Type your text here" style="padding: 10px; font-size: 16px; width: 60%; max-width: 300px;">
      <input type="color" id="textColor" value="#000000" style="padding: 10px; margin-left: 10px;">
    </div>

    <!-- Text Size and Position Sliders with Real-Time Value Display -->
    <div style="margin-top: 20px; text-align: center;">
      <label for="textSize">Text Size: <span id="textSizeValue">100</span></label>
      <input type="range" id="textSize" min="10" max="200" value="100" style="width: 50%; max-width: 300px;">
      <br>
      <label for="textPosX">Position X: <span id="textPosXValue">50</span></label>
      <input type="range" id="textPosX" min="0" max="100" value="50" style="width: 50%; max-width: 300px;">
      <label for="textPosY">Position Y: <span id="textPosYValue">50</span></label>
      <input type="range" id="textPosY" min="0" max="100" value="50" style="width: 80%; max-width: 300px;">
    </div>

    <!-- Invert and Mirror Text Buttons -->
    <div style="margin-top: 20px; text-align: center;">
      <button id="invertText" style="padding: 10px; font-size: 16px;">Invert Text</button>
      <button id="mirrorText" style="padding: 10px; font-size: 16px; margin-left: 10px;">Mirror Text</button>
    </div>

    <!-- Material Selection -->
    <div style="margin-top: 20px; text-align: center;">
      <label for="materialSelect">Choose Material:</label>
      <select id="materialSelect" style="padding: 10px; font-size: 16px;">
        <option value="metal">Metal</option>
        <option value="silver">Silver</option>
        <option value="gold">Gold</option>
      </select>
    </div>

    <!-- Engraving Depth Slider -->
    <div style="margin-top: 20px; text-align: center;">
      <label for="engravingDepth">Engraving Depth: <span id="engravingDepthValue">0.05</span></label>
      <input type="range" id="engravingDepth" min="0.01" max="0.2" step="0.01" value="0.05" style="width: 80%; max-width: 300px;">
    </div>

    <!-- Hidden input to store engraving data for order processing -->
    <input type="hidden" id="engravingDataInput" name="engravingData" value="">

    <!-- Include Three.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

    <!-- Include GLTFLoader for loading 3D models -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>

    <!-- Include OrbitControls -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>

    <!-- Include RGBELoader for HDRI -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/RGBELoader.js"></script>

    <script>
      document.addEventListener('DOMContentLoaded', function() {
        const container = document.getElementById('3d-container');
        const containerWidth = container.clientWidth;
        const containerHeight = container.clientHeight;

        // Initialize Three.js Scene
        const scene = new THREE.Scene();

        // Load HDRI environment
        const rgbeLoader = new THREE.RGBELoader();
        rgbeLoader.load('https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/brown_photostudio_02_1k.hdr', function (texture) {
          texture.mapping = THREE.EquirectangularReflectionMapping;
          scene.environment = texture;
          scene.background = texture; 
        });

        // Initialize Camera
        const camera = new THREE.PerspectiveCamera(75, containerWidth / containerHeight, 0.1, 1000);
        camera.position.set(0, 2, 5);

        // Initialize Renderer
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(containerWidth, containerHeight);
        renderer.physicallyCorrectLights = true;

        renderer.toneMapping = THREE.ACESFilmicToneMapping;
        renderer.toneMappingExposure = 2.0;  

        container.appendChild(renderer.domElement);

        // Add Ambient and Directional Lighting
        const ambientLight = new THREE.AmbientLight(0xffffff, 2);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
        directionalLight.position.set(5, 10, 7.5).normalize();
        scene.add(directionalLight);

        // Initialize OrbitControls
        const controls = new THREE.OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true;
        controls.dampingFactor = 0.05;
        controls.enablePan = false;

        let isTextInverted = false;
        let isTextMirrored = false;

        // Load the 3D Model
        const gltfLoader = new THREE.GLTFLoader();
        const modelUrl = "{{ model_url | escape }}";
        gltfLoader.load(modelUrl, function(gltf) {
          const model = gltf.scene;
          scene.add(model);
          model.position.set(0, 0, 0);

          const box = new THREE.Box3().setFromObject(model);
          const center = box.getCenter(new THREE.Vector3());
          model.position.sub(center);

          function updateTextInRealTime() {
            const text = document.getElementById('engraveText').value.trim();
            const color = document.getElementById('textColor').value;
            const textSize = document.getElementById('textSize').value;
            const posX = document.getElementById('textPosX').value;
            const posY = document.getElementById('textPosY').value;
            const material = document.getElementById('materialSelect').value;
            const engravingDepth = document.getElementById('engravingDepth').value;

            document.getElementById('textSizeValue').textContent = textSize;
            document.getElementById('textPosXValue').textContent = posX;
            document.getElementById('textPosYValue').textContent = posY;
            document.getElementById('engravingDepthValue').textContent = engravingDepth;

            const canvas = document.createElement('canvas');
            const context = canvas.getContext('2d');

            const canvasWidth = 1024;
            const canvasHeight = 1024;
            canvas.width = canvasWidth;
            canvas.height = canvasHeight;

            context.clearRect(0, 0, canvasWidth, canvasHeight);
            context.fillStyle = '#ffffff';
            context.fillRect(0, 0, canvasWidth, canvasHeight);

            context.font = `Bold ${textSize}px Arial`;
            context.textAlign = 'center';
            context.textBaseline = 'middle';
            context.fillStyle = color;

            // Adjust the Y-coordinate calculation
            const adjustedPosX = (canvasWidth * posX) / 100;
            const adjustedPosY = (canvasHeight * (100 - posY)) / 100; // Invert Y-axis

            if (isTextInverted) {
              context.scale(-1, 1);
              context.translate(-canvasWidth, 0);
            }

            if (isTextMirrored) {
              context.save();
              context.scale(1, -1);
              context.translate(0, -canvasHeight);
              context.fillText(text, adjustedPosX, canvasHeight - adjustedPosY);
              context.restore();
            } else {
              context.fillText(text, adjustedPosX, adjustedPosY);
            }

            const newTexture = new THREE.CanvasTexture(canvas);
            newTexture.needsUpdate = true;

            const bumpTexture = new THREE.CanvasTexture(canvas);
            bumpTexture.needsUpdate = true;

            const displacementTexture = new THREE.CanvasTexture(canvas);
            displacementTexture.needsUpdate = true;

            model.traverse(function(child) {
              if (child.isMesh) {
                let metalness = 1.0;
                let roughness = 0.15;
                let color = new THREE.Color(0xffffff);

                if (material === 'silver') {
                  roughness = 0.05;
                  color.setHex(0xC0C0C0);
                } else if (material === 'gold') {
                  roughness = 0.15;
                  color.setHex(0xD4AF37);
                } else {
                  roughness = 0.25;
                }

                const textMaterial = new THREE.MeshPhysicalMaterial({
                  map: newTexture,
                  bumpMap: bumpTexture,
                  bumpScale: 0.15,
                  displacementMap: displacementTexture,
                  displacementScale: parseFloat(engravingDepth),
                  roughness: roughness,
                  metalness: metalness,
                  clearcoat: 1.0,
                  envMap: scene.environment,
                  reflectivity: 1.0,
                  transparent: true,
                  color: color,
                  side: THREE.DoubleSide,
                });

                child.material = textMaterial;
                child.material.needsUpdate = true;
              }
            });

            const engravingData = {
              text: text,
              color: color,
              textSize: textSize,
              posX: posX,
              posY: posY,
              isTextInverted: isTextInverted,
              isTextMirrored: isTextMirrored,
              material: material,
              engravingDepth: engravingDepth
            };

            document.getElementById('engravingDataInput').value = JSON.stringify(engravingData);
          }

          document.getElementById('engraveText').addEventListener('input', updateTextInRealTime);
          document.getElementById('textSize').addEventListener('input', updateTextInRealTime);
          document.getElementById('textPosX').addEventListener('input', updateTextInRealTime);
          document.getElementById('textPosY').addEventListener('input', updateTextInRealTime);
          document.getElementById('textColor').addEventListener('input', updateTextInRealTime);
          document.getElementById('materialSelect').addEventListener('change', updateTextInRealTime);
          document.getElementById('engravingDepth').addEventListener('input', updateTextInRealTime);
          document.getElementById('invertText').addEventListener('click', function() {
            isTextInverted = !isTextInverted;
            updateTextInRealTime();
          });
          document.getElementById('mirrorText').addEventListener('click', function() {
            isTextMirrored = !isTextMirrored;
            updateTextInRealTime();
          });

          updateTextInRealTime();

          function animate() {
            requestAnimationFrame(animate);
            controls.update();
            renderer.render(scene, camera);
          }
          animate();
        });
      });
    </script>
  {% endif %}
{% endfor %}

OrbitControls in ThreeJS not working with import map

I’m trying to get a simple ThreeJs with OrbitControls for pan and zoom. I was able to get a working example with an older version (128), but I’m having trouble with the newer r168.

In the example, I’m trying to write the js code directly into an html page, and importing the threejs dependencies using cdn, instead of a local source.

<body>
    <script type="importmap">
        {
            "imports": {
                "three": "https://unpkg.com/[email protected]/build/three.module.js",
                "three/examples/jsm/controls/OrbitControls": "https://unpkg.com/[email protected]/examples/jsm/controls/OrbitControls.js"
            }
        }
    </script>
    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

        // Scene setup
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        
        // Renderer setup
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setClearColor(0x000000); // Set background color to black
        document.body.appendChild(renderer.domElement);

        // Create a cube
        const geometry = new THREE.BoxGeometry();
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        // Position the camera
        camera.position.z = 5;

        // OrbitControls setup
        const controls = new OrbitControls(camera, renderer.domElement);
        controls.enableDamping = true; // Enable smooth damping
        controls.dampingFactor = 0.25; // Adjust the damping factor for smoothness
        controls.enableZoom = true;    // Enable zoom
        controls.enablePan = true;     // Enable panning

        // Animation loop
        function animate() {
            requestAnimationFrame(animate);
            controls.update(); // Required if damping is enabled
            renderer.render(scene, camera);
        }
        animate();

        // Adjust canvas on window resize
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>

The code seems to get an error right at the start, in the import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';.

Any help on what might be going on and how to fix this?

Is my translate between two language(JS and Java) correct?

Please someone tell me what’s wrong with my code.
I translate the code from JavaScript to Java, but I think there must be something problem in it, because it doesn’t work as expected.
BTW, I am not good at JavaScript, if you can tell me what’s wrong with my code in Java,
that’s awesome

Tips: the code following is a certain encrypt method

//...
info = JSON.stringify(info);

                function encode(str, key) {
                    if (str === '') return '';
                    var v = s(str, true);
                    var k = s(key, false);
                    if (k.length < 4) k.length = 4;
                    var n = v.length - 1,
                        z = v[n],
                        y = v[0],
                        c = 0x86014019 | 0x183639A0,
                        m,
                        e,
                        p,
                        q = Math.floor(6 + 52 / (n + 1)),
                        d = 0;

                    while (0 < q--) {
                        d = d + c & (0x8CE0D9BF | 0x731F2640);
                        e = d >>> 2 & 3;

                        for (p = 0; p < n; p++) {
                            y = v[p + 1];
                            m = z >>> 5 ^ y << 2;
                            m += y >>> 3 ^ z << 4 ^ (d ^ y);
                            m += k[p & 3 ^ e] ^ z;
                            z = v[p] = v[p] + m & (0xEFB8D130 | 0x10472ECF);
                        }

                        y = v[0];
                        m = z >>> 5 ^ y << 2;
                        m += y >>> 3 ^ z << 4 ^ (d ^ y);
                        m += k[p & 3 ^ e] ^ z;
                        z = v[n] = v[n] + m & (0xBB390742 | 0x44C6F8BD);
                    }

                    return l(v, false);
                }

                function s(a, b) {
                    var c = a.length;
                    var v = [];

                    for (var i = 0; i < c; i += 4) {
                        v[i >> 2] = a.charCodeAt(i) | a.charCodeAt(i + 1) << 8 | a.charCodeAt(i + 2) << 16 | a.charCodeAt(i + 3) << 24;
                    }

                    if (b) v[v.length] = c;
                    return v;
                }

                function l(a, b) {
                    var d = a.length;
                    var c = d - 1 << 2;

                    if (b) {
                        var m = a[d - 1];
                        if (m < c - 3 || m > c) return null;
                        c = m;
                    }

                    for (var i = 0; i < d; i++) {
                        a[i] = String.fromCharCode(a[i] & 0xff, a[i] >>> 8 & 0xff, a[i] >>> 16 & 0xff, a[i] >>> 24 & 0xff);
                    }

                    return b ? a.join('').substring(0, c) : a.join('');
                }

                return '{SRBX1}' + base64.encode(encode(info, token));
//...
//...
private static String encode(String str,String key) {
        if(str==null||key==null)
            throw new RuntimeException("null is not allowed!");
        if (str == "") return "";
        var v = s(str, true);
        var k = s(key, false);
        if (k.length < 4) Arrays.copyOf(k, 4);
        int n = v.length - 1,
            z = v[n],
            y = v[0],
            c = 0x86014019 | 0x183639A0,
            m,
            e,
            p,
            q = (int)Math.floor(6 + 52 / (n + 1)),
            d = 0;

        while (0 < q--) {
            d = d + c & (0x8CE0D9BF | 0x731F2640);
            e = d >>> 2 & 3;

            for (p = 0; p < n; p++) {
                y = v[p + 1];
                m = z >>> 5 ^ y << 2;
                m += y >>> 3 ^ z << 4 ^ (d ^ y);
                m += k[p & 3 ^ e] ^ z;
                z = v[p] = v[p] + m & (0xEFB8D130 | 0x10472ECF);
            }

            y = v[0];
            m = z >>> 5 ^ y << 2;
            m += y >>> 3 ^ z << 4 ^ (d ^ y);
            m += k[p & 3 ^ e] ^ z;
            z = v[n] = v[n] + m & (0xBB390742 | 0x44C6F8BD);
        }
        String[] v1 = new String[v.length];
        for(int i = 0 ;i<v.length;i++)
            v1[i] = Integer.toString(v[i]);

        return l(v1, false);
    }

    private static int cPointCheck(String a,int cPointIndex){
        if(cPointIndex<a.length())
            return a.codePointAt(cPointIndex);
        else
            return 0;
    }

    private static int[] s(String a, boolean b) {
        var c = a.length();
        var v = new int[c];

        for (var i = 0; i < c; i += 4) {
            v[i >> 2] = cPointCheck(a, i) | cPointCheck(a, i+1) << 8 | cPointCheck(a, i+2) << 16 | cPointCheck(a, i+3) << 24;
        }

        if (b) v[v.length-1] = c;
        return v;
    }

    private static String l(String[]a, boolean b) {
        var d = a.length;
        var c = d - 1 << 2;

        if (b) {
            var m = Integer.parseInt(a[d - 1]);
            if (m < c - 3 || m > c) return null;
            c = m;
        }

        for (var i = 0; i < d; i++) {
            a[i] = new String(new char[]{(char)(Integer.parseInt(a[i]) & (0xff)), (char)(Integer.parseInt(a[i]) >>> 8 & (0xff)), (char)(Integer.parseInt(a[i]) >>> 16 & (0xff)), (char)(Integer.parseInt(a[i]) >>> 24 & (0xff))});
        }

        return b ? String.join("",a).substring(0, c) : String.join("",a);
    }

   public static String getUserInfoEncoded(String info,String token){
        return "{SRBX1}" + encodeUserInfo(encode(info, token));
   }
//...

Page Break using Javascript Jquery in view and Print

I have this code which I want to use pagebreak when the data in the first page is overlap in must goes to the next page since the size of my container-body3 paper is A4 and I tried dynamically but it didn’t work until, can someone help me with this? Im out of option

enter image description here

function printForms() {
  window.print();
}
<style>     
        .container-wrapper {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: flex-start;
          height: auto;
          padding-bottom: 50px;
          background-color: #cccccc;
        }
          
        .container {
          display: flex;
          justify-content: space-between;
          align-items: center;
          width: 100%;
          height: 5%;
          background-color: #f0f0f0;
          border-radius: 8px;
          box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2);
          margin-bottom: 20px;
          padding: 0 10px;
        }
          
        .print-button {
          background-color: #b2c2ce;
          color: white;
          border: none;
          border-radius: 4px;
          padding: 8px 12px;
          cursor: pointer;
          margin-right: 500px;
        }

        .container-body3  {
          width: 210mm;
          height:297mm;
          background-color: #ffffff;
          box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.5);
          display: flex;
          flex-direction: column;
          padding: 20px;
          position: relative;
          padding: 50px;
        }
        .appendix {
          position: absolute;
          top: 65px;
          right: 50px;
          font-size: 14px;
          font-style: italic;
        }
          
          table {
            border: 3px solid;
            border-collapse: collapse;
            width: 100%;
            margin-top: 40px;
          }
          
          th,
          td {
            border: 1px solid #000000;
            text-align: left;
            padding: 8px;
          }
          
          th {
            background-color: #f2f2f2;
          }
          
          .center-text {
            text-align: center;
            vertical-align: top;
          }
          .dvnumber {
            background-color:#c6e0b4;
            border:1.8px solid;
            font-size: 15px;
          }
        .coloredrow {
          background-color: rgb(158, 198, 255);
          -webkit-print-color-adjust: exact;
        }
        .align-u-left {
          text-align: left;
          vertical-align: top;
        }
        
        table.myClass * { /*new*/
          border: 0;
        }
         
        @media print {
          .container {
          display: none;
        }
        
        .container-body3 {
          page-break-inside: auto;
          margin: 0;
        }
        .page-break {
          page-break-before: always;
        }
        .header {
          margin-top: 0; /* Default margin for the header */
        }
        
        @page {
          margin: 10mm; /* Default margin for the whole page */
        }
        
        .header.large-margin {
          margin-top: 50mm; /* Adjust this value as needed */
        }
        
        .page-start-5 ~ .header {
          margin-top: 50mm; /* Larger margin to simulate a new header for pages starting after page 4 */
        }
        
        .container-body3{
          background-color: #f0f0f0;
          box-shadow: none;
          width: 210mm;
          height: 297mm;
          margin-top: -30px;
        }
        
          .container h3 {
            color: transparent;
          }
        
          .container-wrapper {
            align-items: flex-start;
          }
        
          table {
            margin-top: 15px;
            border: 3px solid;
          }
        
          .appendix {
            top: 45px;
          }
        
          /* Adjust font size for Disbursement Voucher in print */
          .center-text b {
            font-size: 14px;
          }
          .dvnumber {
            background-color: #c6e0b4 !important;
            -webkit-print-color-adjust: exact;
            color: black; /* Make sure text remains readable */
            border: 1.8px solid;
            font-size: 15px;
          }
        
        .container-body3{
          page-break-before: always;
        }
        .footer {
          margin-top: 95% !important;
        }}
        
        .innerTable{
          margin:0px;
          border-color:white;  
        }
        .lastRow{
          padding:0px;
        }
        
        .align-text-right{
        text-align: right;
        }
        .align-text-right{
        text-align: right;
        }
        .no-border{
        border: 0;
        }
        
        .footer {
        margin-top: 99%;
        }
        
        </style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>

<html>
 
    <body>
        <div class="container-wrapper">
            <div class="container">
              <h3></h3>
    
              <button class="print-button" onclick="printForms()">Print</button>
    
            </div>
            <div class="container-body3">
                <br><br><br>
                <span style="font-family: Calibri, sans-serif;" ><center>TESTING HEADER HEADER HEADER HEADER<br> SUB HEADER / SUB HEADER / SUB<br> no# 24-03-767 <br> for January 29, 2024</center></span>
                <table style="font-family: Calibri, sans-serif;" >
                <thead></thead>
                <tbody>
                    <tr >
                    <td><b>No.</b></td>
                    <td><b>Account Number</b></td>
                    <td><b>ID NUMBER</b></td>
                    <td><b><center>NAME</center></b></td>
                    <td><b>AMOUNT</b></td>
                    <td><b>CHARGE</b></td>
                    <td><b><center>PURPOSE</center></b></td>
                    
                    </tr>              
                 
                    <tr>
                    <td class="align-text-right" style="padding: 2; width:6%">1</td>
                    <td class="align-text-right" style="padding: 4;">367167793</td>
                    <td class="align-text-left" style="padding: 4;">16-10653</td>
                    <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                    <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                    <td class="align-text-left" style="padding: 4;">Charge test</td>
                    <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="ali  gn-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>
                    <tr>
                      <td class="align-text-right" style="padding: 2; width:6%">1</td>
                      <td class="align-text-right" style="padding: 4;">367167793</td>
                      <td class="align-text-left" style="padding: 4;">16-10653</td>
                      <td  class="align-text-left" style="padding: 4;">Santiago, Bruise N. </td>
                      <td style="padding: 4;" class="align-text-right">5,454,545.00</td>
                      <td class="align-text-left" style="padding: 4;">Charge test</td>
                      <td class="align-text-left" style="padding: 4;">TE for Mar 2024</td>
                    </tr>

                </tbody>
                </table>

                <table  style="border: 0; font-family: Calibri, sans-serif;" class="myClass" cellspacing="0" cellpadding="0" width="100%">
                <tbody>
                    <tr>
                    <td>
                        <table style="border: 0;">
                        <tbody>
                            <tr>
                            <td style="width: 0px;border:0;"></td>
                            <td style="width: 30px;border:0;"></td>
                            <td style="width: 100px;border:0;"></td>
                            </tr>
                            <tr>
                            <td style="font-size: 13px;padding: 0;" colspan="2" class="no-border">PREPARED BY:</td>
            
                            </tr>
                            <tr>
                            <td class="no-border"></td>
            
                            </tr>
                            <tr>
                            <td class="no-border"></td>
                            <td class="no-border" colspan="2" >
                                <!-- <center><b><u>Janice UUUUU</u></b></center> -->
                                <center><b><u><span contenteditable="true" id="editableName">Reymark Santiago</span></u></b></center>
                            </td>
                            </td>
                            </tr>
                            <tr>
                            <td class="no-border"></td>
                            <td class="no-border" colspan="2">
                                <center><span contenteditable="true" id="editablePosition">AAAA III</span></center>
                            </td>
                            </tr>
            
            
                        </tbody>
                        </table>
                    </td>
                    <td>
                        <table style="border: 0;">
                        <tbody>
                            <tr>
                            <td style="width: 140px;border:0;"></td>
                            <td style="width:80px;border:0;"></td>
                            <td style="width:72px;border:0;"></td>
                            <td style="border:0;"></td>
            
                            </tr>
                            <tr>
                            <td style="font-size: 15px;background-color:rgb(158, 198, 255); padding: 0;" class="no-border coloredrow"><b>CHARGE</b></td>
                            <td style="font-size: 15;background-color:rgb(158, 198, 255); padding: 0; text-align: right;" colspan="2" class="no-border coloredrow"><b>Sum of AMOUNT</b></td>
                            </tr>
            
                           
                            <tr>
                            <td style="padding: 0;" class="no-border"> charges</td>
                            <td style="padding: 0; text-align: right;" class="no-border" colspan="2">
                                5,482,119.00
                            </td>
                            </tr>
                            <tr>
                            <td style="padding: 0;;background-color:rgb(158, 198, 255);" class="no-border coloredrow"><b>GRAND Total</b></td>
                            <td style="padding: 0;background-color:rgb(158, 198, 255); text-align: right;"  class="no-border coloredrow" colspan="2"><b>5,482,119.00</b></td>
                            </tr>
                        </tbody>
                        </table>
                    </td>
                    </tr>
                </tbody>
                </table>
                
            </div>
        </div>
    </body>

</html>

Execute a function after popup window is closed

I have a popup window that I create as follows:

popupWindow = window.open("about:blank", "_blank", "popup=yes");

And I have a function afterFn() that I need to execute after the popupWindow is closed.

My current approach is as follows:

async function pollPopupWindow() {
  while (popupWindow) {
    await new Promise((r) => setTimeout(r, 1000));
    if (popupWindow.closed) {
      popupWindow = null;
      afterFn();
    }
  }
}
pollPopupWindow();

I was wondering if it’s possible to simply execute the afterFn() at the popup window closing time? I tried the following code but it did not work

popupWindow.addEventListener("beforeunload", () => {
  afterFn();
});

any ideas?

my Model.create() in sequelize and node.js does not save data on mysql database

I working on creating a detabase using mysql and node.js and sequelize . my model is saved on my database as i ordered but when i want send data it does not work
here is my codes
Database.js

const { Sequelize } = require("sequelize");
const sequelize = new Sequelize("node-compelet", "root", "zahra@1996", {
  dialect: "mysql",
  host: "localhost",
});
module.exports = sequelize;

and my Model called product.js

const sequelize = require("../util/database");
const { Sequelize, DataTypes } = require("sequelize");

const Product = sequelize.define("Product", {
  id: {
    type: DataTypes.INTEGER,
    autoIncrement: true,
    allowNull: false,
    primaryKey: true,
  },
  title: { type: DataTypes.STRING },
  price: { type: DataTypes.DOUBLE, allowNull: false },
  imgUrl: { type: DataTypes.STRING, allowNull: false },
  description: { type: DataTypes.STRING, allowNull: false },
});
module.exports = Product;

and my controller :

const Product = require("../models/product")
exports.postAddProduct = (req, res, next) => {
  const title = req.body.title;
  const imgUrl = req.body.imgUrl;
  const price = req.body.price;
  const description = req.body.description;
  console.log(req.body);
  Product.create({
    title: title,
    price: price,
    imgUrl: imgUrl,
    description: description,
  })
    .then((result) => {
      console.log("result");
      res.redirect("/");
    })
    .catch((err) => console.log(err));
};

and my app.js

const sequelize = require("./util/database");
const Product = require("../models/product")
sequelize
  .sync({ force: true })
  .then((result) => {
    app.listen(3000);
    console.log("synced secceed");
  })
  .catch((err) => {
    console.log(err);
    console.log("faild");
  });

every time I tried to send data from my form to database nothing happens and just my web page continue loading . also in my controller I tried to log received data but it didn’t worked . I got no error message . it seems that my model don’t work properly .
I checked router and my functions was added properly there .

Best way to remove gaps on candlestick chart using JS Observable Plot (d3)?

I have been working on a candlestick chart using Observable Plot, and I have come across a problem with gaps in the chart. In my dataset, there are of course gaps for weekends when no trading occurs, but I did not expect these gaps to appear in the final plot. This is my first time using Observable Plot.

const ticker = parseDates(tickerData);
const radioBtns = document.getElementsByName("chartType");
let chartType;

for(var i = 0; i < radioBtns.length; i++) {
  radioBtns[i].onclick = updateChart;
}

updateChart();

function updateChart() {
  // reset images
  candlestickLabel.childNodes[0].src = "assets/candlestick-unselected.png";
  lineLabel.childNodes[0].src = "assets/line-unselected.png";
  areaLabel.childNodes[0].src = "assets/area-unselected.png";

  for (let i = 0; i < radioBtns.length; i++) {
    // loop through radio buttons
    if (radioBtns[i].checked) {
      // set chartType to the value of the selected button
      chartType = radioBtns[i];
      
      // loop through labels and set the image to selected if checked
      const labels = document.getElementsByTagName("label");
      for (let j = 0; j < labels.length; j++) {
        if (labels[j].htmlFor == radioBtns[i].id) {
          labels[j].childNodes[0].src = "assets/" + chartType.value + "-selected.png";
        }
      }
    }
  }

  // set up chart based on selected type
  let plot = null;

  if (chartType.value == "candlestick") {plot = Plot.plot({
      inset: 20,
      width: 1000,
      height: 400,
      grid: true,
      x: {
        domain: [ticker[0].date, ticker[ticker.length - 1].date],
        reverse: true,
        tickFormat: d => Plot.formatIsoDate(d), // Format ticks as dates
        tickRotate: -15,
        tickPadding: 5,
      },
      y: {
        label: "↑ Stock price ($)"
      },
      color: {
        domain: [-1, 0, 1],
        range: ["#f23645", "currentColor", "#138808"]
      },
      marks: [
        Plot.ruleX(ticker.filter(d => d.low), {
          x: "date",
          y1: "low",
          y2: "high",
          stroke: d => Math.sign(d.close - d.open),
        }),
        Plot.ruleX(ticker, {
          x: "date",
          y1: "open",
          y2: "close",
          stroke: d => Math.sign(d.close - d.open),
          strokeWidth: 4,
          strokeLinecap: "butt"
        })
      ]
    });
  } else if (chartType.value == "line") {
    plot = Plot.plot({
      inset: 6,
      // width and height match that of container
      width: 1000,
      height: 400,
      grid: true,
      x: {
        // set the domain
        domain: [new Date(ticker[0].date), new Date(ticker[ticker.length - 1].date)],
        reverse: true
      },
      y: {
        label: "↑ Stock Price ($)"
      },
      marks: [
        Plot.lineY(ticker, {
          x: "date",
          y: "close",
          stroke: "#6495ed"
        })
      ]
    });
  } else {
    plot = Plot.plot({
      inset: 6,
      // width and height match that of container
      width: 1000,
      height: 400,
      grid: true,
      x: {
        // set the domain
        domain: [new Date(ticker[0].date), new Date(ticker[ticker.length - 1].date)],
        reverse: true
      },
      y: {
        label: "↑ Stock Price ($)"
      },
      marks: [
        Plot.lineY(ticker, {
          x: "date",
          y: "close",
          stroke: "#6495ed"
        }),
        Plot.areaY(ticker, {
          x: "date",
          y1: Math.min(...ticker.map((t) => t.close)) - 10,
          y2: "close",
          fill: "#6495ed",
          fillOpacity: 0.3
        })
      ]
    });
  }

  const div = chartDiv;
  div.innerHTML = "";
  div.append(plot);
}

// UTILITY FUNCTIONS

const weeks = (start, stop, stride) => d3.utcMonday.every(stride).range(start, +stop + 1);
const weekdays = (start, stop) => d3.utcDays(start, +stop + 1).filter(d => d.getUTCDay() !== 0 && d.getUTCDay() !== 6);

function parseDates(data) {
  return data.map(d => ({
    ...d,
    date: new Date(d.date)  // Ensure `date` is a Date object
  }));
}

Here is my dataset format:

const tickerData = [{
          date: "2024-09-10",
          open: 204.2000,
          high: 205.8300,
          low: 202.8700,
          close: 205.3200,
          volume: 3070644
        },{
          date: "2024-09-09",
          open: 201.9400,
          high: 205.0500,
          low: 201.4300,
          close: 203.5300,
          volume: 3705004
        },{
          date: "2024-09-06",
          open: 202.3800,
          high: 204.1000,
          low: 199.3350,
          close: 200.7400,
          volume: 3304491
        }
}]

I have tried several solutions, but to no avail. First I made sure that the dataset was parsed correctly and contained no weekend data. I have also tried several things using the tick, tickFormat, and domain options for the x-axis.

How to make Parse server login — case insensitive?

I have Parse server with MongoDB and KMP app where login method.

@POST("login")
@Headers(
    value = [
        "${ParseHeaders.CONTENT_TYPE}: application/json",
        "${ParseHeaders.APPLICATION_ID}: ${ParseConstants.APPLICATION_ID}",
        "${ParseHeaders.REST_API_KEY}: ${ParseConstants.REST_API_KEY}",
    ],
)
suspend fun logIn(@Body credentials: ParseLoginCredentials): ParseUserResponse

I need to make the username case-insensitive. Currently, usernames are stored in MongoDB in a disorganized way. We need to structure this on the server side, so the login username in the Parse server must be case-insensitive. I don’t see any login functions in the Parse backend code, yet the login works for some reason. Perhaps it’s handled internally by Parse. I’ve written an interceptor in the Parse server code, but it’s not working.

app.post('/login', function(req, res) {
  let fs = require('fs');
  let path = require('path');
  let bodyParser = require('body-parser');

  app.use(bodyParser.json());

  const { username, password } = req.body;

  if (!username || !password) {
    return res.status(400).send('Username and password are required');
  }

  const lowercasedUsername = username.toLowerCase();
  const loginRequest = new Parse.Query(Parse.User);
  loginRequest.equalTo("username", lowercasedUsername);

  loginRequest.first().then(function(user) {
    if (user) {
      const userStoredUsername = user.get("username").toLowerCase();

      if (userStoredUsername === lowercasedUsername) {
        user.authenticate(password).then(function(isAuthenticated) {
          if (isAuthenticated) {
            res.status(200).json({
              objectId: user.id,
              sessionToken: user.getSessionToken(),
            });
          } else {
            res.status(401).send('Invalid credentials');
          }
        }).catch(function(err) {
          res.status(500).send('Error authenticating user: ' + err.message);
        });
      } else {
        res.status(401).send('Invalid credentials');
      }
    } else {
      res.status(401).send('Invalid credentials');
    }
  }).catch(function(err) {
    res.status(500).send('Error finding user: ' + err.message);
  });
});

Is there any option to handle this on the MongoDB side? Or how can it be done with Parse Server? Do I need to write additional code, such as a case-insensitive login hook, or is there another solution?

I also tried modifying and hiding some indexes in the `_User` entity on MongoDB, but it had no effect.
enter image description here

Change select visible value while dropdown text remains unchanged

I have

    <?php
    $option_select=function($opt_val){
        if($opt_val==$_GET["order"]) {
            echo "selected";
        }
    };
    ?>

<form name="sort" id="sort" action="matches.php" method="get" style="float:right; margin:10px;">
    
    <select name="order" id="order" class="order_select" onchange="changeSort()">
        <option <?php $option_select("last_online"); ?> value="last_online">Last online</option>
        <option <?php $option_select("age_asc"); ?> value="age_asc">Age (Young to Old)</option>
        <option <?php $option_select("age_desc"); ?> value="age_desc">Age (Old to Young)</option>
        <option <?php $option_select("height_asc"); ?> value="height_asc">Height (Short to Tall)</option>
        <option <?php $option_select("height_desc"); ?> value="height_desc">Height (Tall to Short)</option>
        <option <?php $option_select("created_asc"); ?> value="created_asc">Date subscribed (New to Old)</option>
        <option <?php $option_select("created_desc"); ?> value="created_desc">Date subscribed (Old to New)</option>
    </select>
    <input type="submit" value=" Sort " class="btn btn-info" hidden/>
    </form>


<script>

var orderSelector = document.getElementById("order");
orderSelector.options[orderSelector.selectedIndex].text = "Sorted by: " + orderSelector.options[orderSelector.selectedIndex].text;

function changeSort() {
    var orderSelector = document.getElementById("order");
    orderSelector.options[orderSelector.selectedIndex].text = "Sorted by: " + orderSelector.options[orderSelector.selectedIndex].text;
    
    var orderForm = document.getElementById("sort");
    orderForm.submit();
}

</script>

I need the select field to show “Sort by: ” + selected value, however while keeping the value in the dropdown not changed.
I.e. dropdown displayed text says “Sort by: Age (Old to Young)”, while inside the dropdown it’s just “Age (Old to Young)” with the standard check on the left.
An example is ebay or amazon.com.

Downloaded PDF shows blank pages when pulling from SQL db

I’m pulling PDF files from a SQL table, and then wanting to show the PDF in a new window rather than download to the user’s computer. I get the data successfully, but when I try to view the PDF I get blank pages. The right number of pages shows but content is blank. Can’t understand what’s happening. Here is my code:

        var ms = new Date();
        var params = "action=DownloadFile2&ms=" + ms.getTime() + "&file_id=" + file_id;
        var url = urlPath + params;
        $.ajax({
            type: "POST",
            method: "POST",
            responseType: "blob",
            url: url,
            
            success: function (data) {
                var file = new Blob([data], { type: 'application/pdf' });
                var fileURL = URL.createObjectURL(file);
                window.open(fileURL, '', "height=1000, width=2000");
            }

Code behind: If IsDBNull(dt) = True Then Exit Sub

    Dim filename As String
    filename = Trim(dt.Rows(0)("Name").ToString())

    Dim filetype As String
    filetype = Trim(dt.Rows(0)("File_Type").ToString())

    Dim encodedBytes As Byte() = Convert.FromBase64String(Convert.ToBase64String(CType(dt.Rows(0)("Data"), Byte())))

    HttpContext.Current.Response.Clear()
    HttpContext.Current.Response.AddHeader("Pragma", "public")
    HttpContext.Current.Response.AddHeader("Cache-Control", "max-age=0")
    HttpContext.Current.Response.AddHeader("Content-disposition", "attachment;filename=" & filename)
    HttpContext.Current.Response.ContentType = "application/pdf"
    HttpContext.Current.Response.SuppressContent = False
    Response.Headers.Add("Content-Length", encodedBytes.Length.ToString())

    Dim outputStream As Stream = HttpContext.Current.Response.OutputStream

    outputStream.Write(encodedBytes, 0, encodedBytes.Length)
    outputStream.Flush()
    outputStream.Close()

I tried to open the PDF in a new window, I just get blank pages. One document showed page 1 and rest blank.

How to properly infer the Constructor of an object through JSDoc?

I want to make this function that receives a parameter and return its class if object, the parameter itself if function or the legacy object constructor if anything else.

In JavaScript the example below covers the functionality for most cases. But the JSDoc doesn’t follow…

export const ParseType = ( Subject ) =>
{
   if ( ( typeof Subject == 'function' ) && ( typeof Subject.prototype == 'object' ) )
   {
      return Subject;
   }
   
   return Object(Subject).constructor;
}

function MyCustomType ()
{
   
}
// JSDoc signature: () => void

const MyCustomInstance = new MyCustomType;
// JSDoc signature: any
// Expecting JSDoc signature: MyCustomType

const MyRetrievedCustomType = ParseType(MyCustomInstance);
// JSDoc signature: any
// Expecting JSDoc signature: typeof MyCustomType

To fix this issue, I can do something like this:


/**
 * @template [Type = InstanceType < typeof Object >]
 * @param { Type } [Subject = Type]
 */
export const ParseType = ( Subject ) =>
{
   let Inferred;
   
   if ( ( typeof Subject == 'function' ) && ( typeof Subject.prototype == 'object' ) )
   {
      Inferred =
      (
         /**
          * @type { Type extends Function & { prototype: {} } ? Type : never }
          */
         ( Subject )
      );
   }
   
   else
   {
      const Instance =
      (
         /**
          * @type { Subject & {} }
          */
         ( Object(Subject) )
      );
      
      Inferred =
      (
         /**
          * @type { Type extends Function & { prototype: {} }
          *          ? never
          *          : Instance extends { constructor: infer Constructor }
          *             ? Constructor
          *             : never
          *       }
          */
         ( Instance.constructor )
      );
   }
   
   return Inferred;
}

/**
 * @constructor
 */
function MyCustomType ()
{
   
}
// JSDoc signature: typeof MyCustomType

const MyCustomInstance = new MyCustomType;
// JSDoc signature: MyCustomType

const MyRetrievedCustomType = ParseType(MyCustomInstance);
// JSDoc signature: Function
// Expected JSDoc signature: typeof MyCustomType
// JavaScript actual value: [Function MyCustomType]

const MyRegrievedStringType = ParseType('MyString');
// JSDoc signature: Function
// Expected JSDoc signature: StringConstructor
// JavaScript actual value: [Function String]

I can’t extract the constructor from Instance correctly because JSDoc infers the constructor at ObjectConstructor.constructor which is Function. Oddly enough, when I’m extracting the constructor from Instance, in the casting JSDoc type tag I can test Instance against any class and evaluate as the “hard coded” class…

/**
 * @type { Instance extends MyCustomType ? typeof MyCustomType : never }
 */

Or even chaining like this…

/**
 * @type { Instance extends String ? typeof String : Instance extends BigInt ? typeof BigInt : never : never }
 */

But I can’t just keep increasing this chain and hard coding all the classes that could possibly be used in any project that will use this function…

Google Sign-In in React Native WebView opens new tab in Chrome and does not return to app

I’m using a WebView in my React Native app to load a website with Google Sign-In functionality. However, when I click the “Sign in with Google” button, it opens a new tab in Chrome. After selecting an email for login, the page just keeps showing a loading screen and does not return to the app or proceed with the sign-in.

code :

 <WebView
  allowFileAccess
  allowFileAccessFromFileURLs
  sharedCookiesEnabled
  thirdPartyCookiesEnabled
  nestedScrollEnabled
  userAgent="Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"
  source={{ uri: 'here i provide my url' }} 
  style={{ flex: 1 }}
/>

Problem:
Google Sign-In opens a new Chrome tab instead of staying within the WebView.
After selecting the email for Google login, the process gets stuck on a loading screen and doesn’t proceed further or return to the app.

What I’ve tried:
Enabled third-party cookies (thirdPartyCookiesEnabled).
Set a custom user agent.
Ensured sharedCookiesEnabled is enabled.

Any suggestions on how to fix this issue?

How to find distance between top of element and top of viewable webpage

I have an element that has position sticky and has the top property set to 30px. I want it so that when the element becomes stuck (so to say) It has a class of stuck added to it. I’m aware it can be done with intersectionObserver however I would like to know a way that I could do it in vanilla HTML, CSS or JS.

The way I have thought of so far is to add the class once the elements distance from the top of the viewable webpage is 30px. When researching, I have come across code like this:

var elDistanceToTop = window.pageYOffset + el.getBoundingClientRect().top

Although this does do something, it doesn’t do want I want. What it does is it finds the top of the element to the top of the window height.

(Now at the time of writing this I am not sure if the window height is what it is called but I mean the bit of the webpage that you would get to if you scrolled up until you couldn’t any more. Sometimes it is out of sight).

Using this code, the value I get is always constant as the element is not moving up or down the page, it is only the viewport is moving down the page as you scroll down.

Instead, the value that the function (or whatever) returns should change depending on where you have scrolled to. Before the ‘stuck’ position activates, the distance from the top should vary depending on where you scroll. But once you have hit its ‘stuck’ threshold the distance from the top should stay the same.

I don’t mind the solution as long as it uses HTML, CSS or JS but nothing else.

Bar Icon onTouchEnd problem with animation on mobile device

I created a bar that looks like macOS bar, but when I’m using my phone, I clicked and the animation look like this, like it hasn’t done its hover animation:

clicked

It should look like this when I click (this is on the computer screen with mouse)

pc

I tried to figure out how, and I looked at the onTouch event, but it didn’t fix me; it also affects my tooltip, which can’t be closed when I’m using a mobile device.

This is my snip code BarIcon.js:

const BarIcon = ({ icon, name, url, clickHandler, changeColor, theme }) => {
  const [bounce, setBounce] = useState(false);
  const [hover, setHover] = useState(false);

  const changeHandler = () => {
    setBounce(true);
    setTimeout(() => {
      setBounce(false);
    }, 500);
  };

  const location = useRouter();
  const path = location.pathname;
  const displayNav = path === url;

  const handleClick = () => {
    setHover(false);
    setTimeout(() => {
      changeHandler();
      if (clickHandler) {
        clickHandler();
      }
    }, 50);
  };

  return (
    <div className="Icon--container" alt={name} style={{ position: "relative" }}>
      <div className={bounce ? "Icon--bounce icon2" : "icon2"}>
        <Tag
          pos="fixed"
          top={{ xs: "-37px", md: "-40px" }}
          w="auto"
          d={hover ? "block" : "none"}
          bg={changeColor ? "#fefefe" : "#161616"}
          border="0.5px solid"
          borderColor={changeColor ? "#dbdbdb" : "#3e3e3e"}
          textColor={changeColor ? "#858585" : "#7e7e7e"}
          transition="0.3s"
          zIndex="9999"
        >
          {name}
        </Tag>
        <span
          id="icon"
          className={"Icon Icon" + theme}
          onClick={handleClick}
          onTouchEnd={handleClick} // Đảm bảo xử lý nhấp chuột trên thiết bị di động
          onMouseEnter={() => setHover(true)}
          onMouseLeave={() => setHover(false)}
        >
          <Icon
            name={bounce ? "Loading" : icon}
            color={changeColor ? "#858585" : "#7e7e7e"}
            size="22px"
          />
        </span>
      </div>
      <Icon
        d={displayNav ? null : "none"}
        name="Dot"
        m="auto"
        color={changeColor ? "#dbdbdb" : "#3e3e3e"}
        size="10px"
      />
    </div>
  );
};

And this is my CSS for handling the hover event of the button:

.Icon:hover{
    transform: scale(1.4) translateY(-15px) ;
    margin: 20px 15px 0px 15px;
}
.Icon:not(:hover){
    transform: scale(1) ;
}