How to Resize a Rectangle Using Hover Dots in Three.js While Keeping One Edge Fixed?

I am working on a Three.js project where
I need to resize a rectangle interactively using hover dots.

The rectangle has two hover dots, one on the left edge and one on the right edge. like this in the screenshot
screenshot

Current behavior:
The rectangle’s width increases, when I drag the dots, but it expands in both directions instead of keeping one edge fixed.
gif

The expected behavior is as follows:

Right Dot Dragged Right:

  • The rectangle’s width increases.
  • The rectangle’s left edge remains fixed.
  • The right hover dot moves outward.

Right Dot Dragged Left:

  • The rectangle’s width decreases.
  • The rectangle’s left edge remains fixed.
  • The right hover dot moves inwards

Left Dot Dragged Left:

  • The rectangle’s width increases.
  • The rectangle’s right edge remains fixed.
  • The left hover dot moves outward.

Left Dot Dragged Right (Crossing the Center):

  • The rectangle’s width decreases.
  • The rectangle’s right edge remains fixed.
  • The left hover dot moves inwards.

Here is the code for the handleDotDrag method:

handleDotDrag(mousePosition, camera) {
  if (!this.isResizing || !this.activeDot) return;

  // Convert mouse position to world coordinates
  const vector = new THREE.Vector3(mousePosition.x, mousePosition.y, 0.5);
  vector.unproject(camera);

  const centerX = this.rectangle.position.x;

  if (this.activeDot.name === "leftDot") {
    // Calculate new width based on the left dot's position
    const newWidth = Math.abs(centerX - vector.x) * 2;

    if (newWidth > 0) {
      this.resize(newWidth);

      // Update the rectangle's position to keep the right edge fixed
      const newCenterX = (this.rectangle.position.x + vector.x) / 2;
      this.rectangle.position.x = newCenterX;
    }
  } else if (this.activeDot.name === "rightDot") {
    // Calculate new width based on the right dot's position
    const newWidth = Math.abs(vector.x - centerX) * 2;

    if (newWidth > 0) {
      this.resize(newWidth);

      // Update the rectangle's position to keep the left edge fixed
      const newCenterX = (this.rectangle.position.x + vector.x) / 2;
      this.rectangle.position.x = newCenterX;
    }
  }
}

Questions:

  • How can I ensure that the rectangle’s left or right edge remains fixed while resizing?
  • Is there a better way to implement this functionality in Three.js?

Any help or suggestions would be greatly appreciated! Thank you!

Javascript API call doesnt display the actual HTML just inserts into element [duplicate]

I have the following function in my website…

    function updateFilteredHtml(data) {
        $('#items').html("");
        var htmlItems = "";
         data.map(kc => {

                htmlItems += '<div class="col-md-4"><div class="card mb-4 box-shadow"><img class="card-img-top" src="' + kc.imgUrl + '" alt="Image"><div class="card-body"><p class="card-text"><strong>' + kc.player + '</strong><br>' + kc.cardType + '<br><small style="font-size: 8px; color:white">item #: ' + kc.docId + '</small></p><div class="d-flex justify-content-between align-items-center"><small class="text-muted">' + kc.sport + '</small><small class="text-muted">$10.00</small></div><div style="text-align: center; margin-top:5px;"><form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank"><input type="hidden" name="cmd" value="_s-xclick" /><input type="hidden" name="hosted_button_id" value="' + kc.paypalId + '" /><input type="hidden" name="currency_code" value="USD" />  <input type="image" src="#" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Add to Cart" /></form></div></div></div></div>';
            })

            $('#items').html(htmlItems);
    }

However, when I view the source of the website, I dont see the actual HTML, I just see the code I wrote. When I write websites in PHP, I would see the actual HTML and not the PHP code, which makes sense since PHP is a backend code, Javascript lives on the browser itself.

My question is, is there a way to see the actual HTML when I view the source of the code? My goal is to benefit from SEO.

Nonce not working in browser even though it is set in policy and script

The nonce doesn’t seem to work anywhere. Currently we cut out everything that could make problems, since of course it should be generated, but now it is just static for testing purposes.

Our content policy is defined in our filter:

@Component
public class CSPFilter extends OncePerRequestFilter {

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        HttpServletResponse httpResponse = (HttpServletResponse) response;

        SecureRandom random = new SecureRandom();

        byte[] nonceBytes = new byte[16];

        random.nextBytes(nonceBytes);

        String nonce = Base64.getEncoder().encodeToString(nonceBytes);
        nonce = "static";

        String policy = "default-src 'self'; script-src 'self' 'nonce-" + nonce + "'  img-src 'self'; object-src 'none';";

        var oldHeader = httpResponse.getHeader("Content-Security-Policy");
        if (oldHeader!=null) {
            oldHeader = oldHeader + " " + policy;
            httpResponse.setHeader("Content-Security-Policy", oldHeader);
        }
        else
            httpResponse.setHeader("Content-Security-Policy", policy);

        request.setAttribute("nonce", nonce);

        filterChain.doFilter(request, response);
    }
}

and the html looks like this:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<!DOCTYPE html>
<head>
    <title>Login to ToDo Roo</title>
    <link th:href="@{/main.css}" rel="stylesheet"/>
</head>
<body  nonce="static" class="todoroo-body" onload="test()3">
<script language="text/javascript" nonce="static">function test3(){console.log("this should work")}</script>
<script>function test(){console.log("this shouldn't work")}</script>
<h2 th:nonce="${nonce}" th:text="${nonce}" align="center"></h2>

</body>
</html>

yet all browsers state something like this:

Content-Security-Policy: The page’s settings blocked an event handler
(script-src-attr) from being executed because it violates the
following directive: “script-src ‘self’ ‘nonce-static’ http://img-src
‘self’” Source: test()3

Content-Security-Policy: The page’s settings blocked an inline script
(script-src-elem) from being executed because it violates the
following directive: “script-src ‘self’ ‘nonce-static’ http://img-src
‘self’”

We tried multiple solutions, even putting the content policy into a meta tag and loading the site by drag and drop into the browser. We tried multiple policy options like “unsafe-hashes” or the like to no avail.

chrome.windows.update Does not Focus minimized Chrome Window After Clicking The Notification in Ubuntu Notification Center?

I am developing a Google Chrome Extension where Push Notification send to Ubuntu OS shows it in the floating window and after that it goes to Notification Center.

The idea is to focus the current window and show a extension popup when User clicks on that system notification.

It works when User clicks on the Floating Notification, but it doesn’t work if User opens the Notification Center and clicks the Notification there.

The Chrome window doesn’t get focused (bring to the front) and Inspecting the Extensions reveals the following Error in console:

"Error opening popup. Could not find an active browser window"

Here is the Code I used to handle Notification Click:

chrome.notifications.onClicked.addListener(async function (notificationId) {
  const windows = await chrome.windows.getAll();
  await chrome.windows.update(windows[0].id, {
          focused: true
        });
  await chrome.action.setPopup({popup: 'index.html'});
  await chrome.action.openPopup();
});

How do I build Vue+Vite project that contains web worker and WASM?

In my project, I have a web worker at ./src/test.worker.js that looks like this:

import("mywasm").then(wasm => {
  self.onmessage = event => {
    const { x, y } = event.data
    const z = wasm.func(x, y)
    self.postMessage({ z })
  }
})

I import it in a Vue component this way:

<script setup>
import TestWorker from '@/test.worker.js?worker'
...
const worker = new TestWorker()
worker.onmessage = event => {
  console.log(event.data)
}
...
worker.postMessage({x: 25, y: 36})
...
</script>

If I run this project while developing with npm run dev (in package.json I have scripts.dev: vite and scripts.build: vite build), everything works file. But if I build with NODE_ENV=production npm run build, I get the error:

error during build:
[vite:worker] The "path" argument must be of type string. Received undefined
file: /home/myuser/Development/myproj/src/test.worker.js?worker

This makes me think that on the build stage Vite forgets that ?worker is not a part of the file name, so it can’t find the exact name test.worker.js?worker because instead test.worker.js exists. How do I fix it?. Or is there a way to build the project exactly in the way as vite does on the development server mode? Or maybe I forgot something in vite-plugin-wasm configuration?

My vite.config.js:

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import wasm from "vite-plugin-wasm"
import topLevelAwait from "vite-plugin-top-level-await"

// https://vite.dev/config/
export default defineConfig({
  build: {
    target: 'esnext',
  },
  plugins: [
    vue(),
    vueDevTools(),
    wasm(),
    topLevelAwait(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
  worker: {
    plugins: [
      wasm(),
      topLevelAwait(),
    ],
  },
})

And my package.json:

{
  "name": "myproj",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "description": "",
  "author": "",
  "license": "MIT",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "mywasm": "file:../mywasm/mywasm-pkg",
    "vite-plugin-top-level-await": "^1.5.0",
    "vite-plugin-wasm": "^3.4.1",
    "vue": "^3.5.13",
    "vue-router": "^4.5.0"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.2.0",
    "vite": "^5.4.11",
    "vite-plugin-vue-devtools": "^7.7.2"
  }
}

How to prevent an embedded video from exiting fullscreen-mode due to a reloading component?

I’m working on an Angular application where I display embedded videos using . The videos are part of a list of topics, and each video is shown when a topic is expanded (using *ngIf). Here’s the issue:

Problem: When I click the fullscreen button on the video player (YouTube, for example), the video exits fullscreen immediately or never enters it. It seems like the Angular component reloads or destroys and re-renders the DOM element, causing the fullscreen to close.


<div class="course-container mt-3" *ngIf="topics.length > 0">   <div
*ngFor="let topic of topics; let i = index" class="topic-section">
    <div id="accordion-{{topic.tid}}" class="row">
      <div class="card my-4">
        <div class="topic-card d-flex justify-content-between align-items-center">
          <div class="topic-header row"
            [ngClass]="{ 'disabled-topic': topic.isPaid === 2 && topic.paymentStatus === 0 }">
            <div class="col-md-10">
              <span class="topic-title">Topic {{ i + 1 }} : {{ topic.tname }}</span>
            </div>
            <div class="col-md-1 d-flex">
              <span class="toggle-icon-container col-md-6 d-flex"
                (click)="toggleVideo(topic.tid, topic.isPaid, topic.paymentStatus)"
                [ngClass]="{ rotate: expandedTopicId === topic.tid }">
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
                  <circle cx="12" cy="12" r="10" fill="#dd9fff" />
                  <path d="M8 10l4 4 4-4" stroke="black" stroke-width="2" stroke-linecap="round"
                    stroke-linejoin="round" />
                </svg>
              </span>
            </div>

          </div>
          <div class="col-md-2 d-flex justify-content-center align-items-center">
            <span class="paidStatusLabel" [ngClass]="{
            freePlan: topic.isPaid === 1,
            paidPlanAvailable: topic.isPaid === 2 && topic.paymentStatus === 1,
            paidPlanEnquire: topic.isPaid === 2 && topic.paymentStatus === 0
          }">
              <ng-container *ngIf="topic.isPaid === 2 && topic.paymentStatus === 0; else normalBadge">
                <!-- If Paid but needs Enquiry, show button -->
                <button class="badge badge-warning border-0" (click)="enquire(topic)">
                  Paid – Click Here to Enquire
                </button>
              </ng-container>
              <ng-template #normalBadge>
                <!-- Otherwise, show simple badge -->
                <span class="badge" [ngClass]="{
              'badge-light': topic.isPaid === 1,
              'badge-success': topic.isPaid === 2 && topic.paymentStatus === 1,
            }">
                  {{
                  topic.isPaid === 1
                  ? 'Free'
                  : 'Paid and Available'
                  }}

                </span>
              </ng-template>
            </span>
          </div>
        </div>

        <!-- Videos Section -->
        <div class="videos-container" *ngIf="expandedTopicId === topic.tid">
          <ul class="list-group" style="padding-top: 2rem;padding-bottom: 2rem;">
            <li class="list-group-item" *ngFor="let video of topicVideos[topic.tid]">
              <div *ngIf="video.englishUrl" class="text-center">
                <iframe [src]="sanitizeUrl(video.englishUrl)" 
                  width="40%" height="300" frameborder="0" 
                  allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
                   allowfullscreen>
                </iframe>
                
                  <a [href]="video.englishUrl" target="_blank" rel="noopener">
                    <i class="bi bi-arrows-fullscreen ml-2" title="Open Fullscreen in New Tab"></i>
                  </a>
              
              </div>
            </li>
          </ul>

          <!--  Topic Rating Section  -->
          <div class="rating-container my-3 text-center">
            <p>Rate this Topic</p>
            <div>
              <div class="my-2" style="padding: 1.25rem;">
                <div *ngIf="selectedRatings[topic.topicId] !== undefined">
                  <div *ngIf="emojiKey" [@slideUp]>
                  <span style="font-size: 4rem;">    
                    {{ getEmoji(selectedRatings[topic.topicId]) }}
                  </span>
                  </div>
                </div>
              </div>
              <span *ngFor="let star of [].constructor(starCount); let starIndex = index"
                (click)="rateVideo(topic.topicId, starIndex + 1)"
                style="cursor: pointer; font-size: 3rem; color: gold;">
                {{ showIcon(starIndex, topic.topicId) === 'star' ? '★' : '☆' }}
              </span>
            </div>
          </div>

        </div>

        <div *ngIf="topics.length === 0 && selectedCourseId">
          <p>No topics available for this course.</p>
        </div>
      </div>
    </div>   </div> </div>

>
  constructor(
    private axiosService: AxiosService,
    private toastr: ToastrService,
    private sanitizer: DomSanitizer
  ) { }

  ngOnInit(): void {
    this.axiosService.userId$.subscribe((id) => {
      this.userId = id ? Number(id) : null;
      // this.fetchLastChoice();
    });

    this.getLastViewChoice();


    // for (let index = 0; index < this.starCount; index++) {
    //   this.ratingArr.push(index);
    // }
  }

  sanitizeUrl(url: string): SafeResourceUrl {
    const trustedUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
    console.log('Sanitized URL:', trustedUrl);
    return trustedUrl;
  }

Angular iframe embedded video exits fullscreen immediately due to component reload

I’m working on an Angular application where I display embedded videos using . The videos are part of a list of topics, and each video is shown when a topic is expanded (using *ngIf). Here’s the issue:

Problem: When I click the fullscreen button on the video player (YouTube, for example), the video exits fullscreen immediately or never enters it. It seems like the Angular component reloads or destroys and re-renders the DOM element, causing the fullscreen to close.


<div class="course-container mt-3" *ngIf="topics.length > 0">   <div
*ngFor="let topic of topics; let i = index" class="topic-section">
    <div id="accordion-{{topic.tid}}" class="row">
      <div class="card my-4">
        <div class="topic-card d-flex justify-content-between align-items-center">
          <div class="topic-header row"
            [ngClass]="{ 'disabled-topic': topic.isPaid === 2 && topic.paymentStatus === 0 }">
            <div class="col-md-10">
              <span class="topic-title">Topic {{ i + 1 }} : {{ topic.tname }}</span>
            </div>
            <div class="col-md-1 d-flex">
              <span class="toggle-icon-container col-md-6 d-flex"
                (click)="toggleVideo(topic.tid, topic.isPaid, topic.paymentStatus)"
                [ngClass]="{ rotate: expandedTopicId === topic.tid }">
                <svg width="28" height="28" viewBox="0 0 24 24" fill="none">
                  <circle cx="12" cy="12" r="10" fill="#dd9fff" />
                  <path d="M8 10l4 4 4-4" stroke="black" stroke-width="2" stroke-linecap="round"
                    stroke-linejoin="round" />
                </svg>
              </span>
            </div>

          </div>
          <div class="col-md-2 d-flex justify-content-center align-items-center">
            <span class="paidStatusLabel" [ngClass]="{
            freePlan: topic.isPaid === 1,
            paidPlanAvailable: topic.isPaid === 2 && topic.paymentStatus === 1,
            paidPlanEnquire: topic.isPaid === 2 && topic.paymentStatus === 0
          }">
              <ng-container *ngIf="topic.isPaid === 2 && topic.paymentStatus === 0; else normalBadge">
                <!-- If Paid but needs Enquiry, show button -->
                <button class="badge badge-warning border-0" (click)="enquire(topic)">
                  Paid – Click Here to Enquire
                </button>
              </ng-container>
              <ng-template #normalBadge>
                <!-- Otherwise, show simple badge -->
                <span class="badge" [ngClass]="{
              'badge-light': topic.isPaid === 1,
              'badge-success': topic.isPaid === 2 && topic.paymentStatus === 1,
            }">
                  {{
                  topic.isPaid === 1
                  ? 'Free'
                  : 'Paid and Available'
                  }}

                </span>
              </ng-template>
            </span>
          </div>
        </div>

        <!-- Videos Section -->
        <div class="videos-container" *ngIf="expandedTopicId === topic.tid">
          <ul class="list-group" style="padding-top: 2rem;padding-bottom: 2rem;">
            <li class="list-group-item" *ngFor="let video of topicVideos[topic.tid]">
              <div *ngIf="video.englishUrl" class="text-center">
                <iframe [src]="sanitizeUrl(video.englishUrl)" 
                  width="40%" height="300" frameborder="0" 
                  allow="fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
                   allowfullscreen>
                </iframe>
                
                  <a [href]="video.englishUrl" target="_blank" rel="noopener">
                    <i class="bi bi-arrows-fullscreen ml-2" title="Open Fullscreen in New Tab"></i>
                  </a>
              
              </div>
            </li>
          </ul>

          <!--  Topic Rating Section  -->
          <div class="rating-container my-3 text-center">
            <p>Rate this Topic</p>
            <div>
              <div class="my-2" style="padding: 1.25rem;">
                <div *ngIf="selectedRatings[topic.topicId] !== undefined">
                  <div *ngIf="emojiKey" [@slideUp]>
                  <span style="font-size: 4rem;">    
                    {{ getEmoji(selectedRatings[topic.topicId]) }}
                  </span>
                  </div>
                </div>
              </div>
              <span *ngFor="let star of [].constructor(starCount); let starIndex = index"
                (click)="rateVideo(topic.topicId, starIndex + 1)"
                style="cursor: pointer; font-size: 3rem; color: gold;">
                {{ showIcon(starIndex, topic.topicId) === 'star' ? '★' : '☆' }}
              </span>
            </div>
          </div>

        </div>

        <div *ngIf="topics.length === 0 && selectedCourseId">
          <p>No topics available for this course.</p>
        </div>
      </div>
    </div>   </div> </div>

> ```




  constructor(
    private axiosService: AxiosService,
    private toastr: ToastrService,
    private sanitizer: DomSanitizer
  ) { }

  ngOnInit(): void {
    this.axiosService.userId$.subscribe((id) => {
      this.userId = id ? Number(id) : null;
      // this.fetchLastChoice();
    });

    this.getLastViewChoice();


    // for (let index = 0; index < this.starCount; index++) {
    //   this.ratingArr.push(index);
    // }
  }

  sanitizeUrl(url: string): SafeResourceUrl {
    const trustedUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
    console.log('Sanitized URL:', trustedUrl);
    return trustedUrl;
  }

How to implement support for multiple dynamic model responses in deep-chat Angular?

enter image description hereI am working with the deep-chat library and am trying to support multiple models in my setup. Specifically, I want to handle multiple models inside the onMessage event by making manual fetch requests to dynamically selected models.

I’m using the handler function and getting the response from multiple models properly. However, the sender button of the message is still showing as “loading” even after the response is received. You can check the image as well.

I’ve attached a screenshot and included the relevant code I’m using to handle the multiple models:

this.chatRequest = {
"url": this.appService.basePath + "api/providers/cloudlyte/v1/chat/completions",
"method": "POST",
"stream": { simulation: 20 }
};

    setTimeout(() => {
        if (this.chatElementRef) {
            const chatEl = this.chatElementRef.nativeElement;
            chatEl.connect = {
                handler: async (body, signals) => {
                    const modelsToCall = [...this.selectedModelList];
                    await Promise.all(modelsToCall.map(async (model) => {
                        const requestBody = {
                                model,
                                messages: [
                                    {
                                        role: 'user',
                                        content: body.messages[0].text
                                    }
                                ]
                            };
                        const response = await fetch(this.appService.basePath + "api/providers/cloudlyte/v1/chat/completions", {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'Authorization': `Bearer ${this.keyId}`
                            },
                        
                            body: JSON.stringify(requestBody)
                        },)
                        const result = await response.json();
                        if (response.status === 401) {
                                chatEl.addMessage({
                                    text: `${model}: ❌ Unauthorized – check API key.`,
                                    role: 'ai'
                                });
                            } else {
                                const reply = result?.choices?.[0]?.message?.content || 'No reply received';
                                chatEl.addMessage({
                                    text: `${model}: ${reply}`,
                                    role: 'ai'
                                });
                            }
                    }))
                }
            }
       }
    });

<deep-chat
#elementRef
[introMessage]="introMessage"
[textInput]="textInput"
[responseInterceptor]="responseInterceptor"
[demo]="false"
[demoMessage]="null"
[submitButtonStyles]="submitButtonStyles"
[messageStyles]="messageStyles"
[avatars]="avatars"
[connect]="chatRequest"
stream='{"simulation": 6}'
style="
border-radius: 10px;
width: 100%;
height: calc(100vh - 100px);
max-height: 55%;
padding-top: 10px;
font-family: 'Plus Jakarta Sans';
font-size: 0.9rem;
background: #faf8f8;

                  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
                ">
              </deep-chat>

Hide “build” in the URL

After building my Laravel/Vue app in local, the URL looks like http://crm.local/**build**/login.

I’m using Vite as a frontend server and there is the content of vite.config.js:

import { fileURLToPath } from 'node:url'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import laravel from 'laravel-vite-plugin'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { defineConfig } from 'vite'
import vuetify from 'vite-plugin-vuetify'
import svgLoader from 'vite-svg-loader'

// https://vitejs.dev/config/
export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        api: 'modern',
        quietDeps: true,
        quiet: true,
      },
    },
  },
  plugins: [vue({
    template: {
      transformAssetUrls: {
        base: null,
        includeAbsolute: false,
      },
    },
  }), vueJsx(), laravel({
    input: ['resources/js/main.js'],
    refresh: true,
  }), // Docs: https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin
  vuetify({
    styles: {
      configFile: 'resources/styles/variables/_vuetify.scss',
    },
  }), Components({
    dirs: ['resources/js/@core/components', 'resources/js/components'],
    dts: true,
  }), // Docs: https://github.com/antfu/unplugin-auto-import#unplugin-auto-import
  AutoImport({
    imports: ['vue', 'vue-router', '@vueuse/core', '@vueuse/math', 'pinia'],
    vueTemplate: true,

    // ℹ️ Disabled to avoid confusion & accidental usage
    ignore: ['useCookies', 'useStorage'],
    eslintrc: {
      enabled: true,
      filepath: './.eslintrc-auto-import.json',
    },
  }), svgLoader()],
  define: { 'process.env': {} },
  resolve: {
    alias: {
      '@core-scss': fileURLToPath(new URL('./resources/styles/@core', import.meta.url)),
      '@': fileURLToPath(new URL('./resources/js', import.meta.url)),
      '@core': fileURLToPath(new URL('./resources/js/@core', import.meta.url)),
      '@layouts': fileURLToPath(new URL('./resources/js/@layouts', import.meta.url)),
      '@images': fileURLToPath(new URL('./resources/images/', import.meta.url)),
      '@styles': fileURLToPath(new URL('./resources/styles/', import.meta.url)),
      '@configured-variables': fileURLToPath(new URL('./resources/styles/variables/_template.scss', import.meta.url)),
    },
  },
  build: {
    chunkSizeWarningLimit: 5000,
  },
  optimizeDeps: {
    exclude: ['vuetify'],
    entries: [
      './resources/js/**/*.vue',
    ],
    include: ['fast-deep-equal'],
  },
})

And there is my vhost:

<VirtualHost *:80>
    ServerName crm.local
    ServerAlias www.crm.local
    DocumentRoot "D:/crm/public"
    ErrorLog "logs/crm.local-error.log"
    <Directory "D:/crm/public">
    AllowOverride All
        Require all granted    
    </Directory>
</VirtualHost>

When I open the app on the browser, after running vite build, I can see the webpage, but I want to remove the build term in the URL.

I tried to add base: '/' in the vite.config.js file to remove it, but it damages all styles.

The build folder is located at D:/crm/public/.

Any help?

How can I use Playwright to interact with Chrome’s Context Menu in E2E tests?

I am working on a Chrome Extension that creates a custom Context Menu option that is available when the user highlights text and right clicks it on any background page.

Chrome’s default context menu options + my custom ‘Add Word’ option

All of this functionality works perfectly when I am manually testing the application but I would like to add E2E tests that test clicking this option. I am using Playwright to write my E2E tests and my custom ‘Add Word’ option does show up while in debug mode.

Playwright Debug Screenshot of my custom ‘Add Word’ option

My only question is how can I interact with Chrome’s Context Menu options through Playwright?

I have tried using Keyboard Shortcuts like ‘Shift+F10’ to open the context menu and using ‘ArrowUp’ and ‘ArrowDown’ commands to traverse through the menu. I have tried to find the ‘Add Word’ menu by using the ‘page.getByText(‘Add Word’)’ and ‘getByRole(‘button’, { name: ‘Add Word’ })’ selectors to no avail. I have tried using right click options. I also tried clicking at specific coordinates using this ‘page.mouse.click’ API at the coordinates of the context menu to no avail: https://playwright.dev/docs/api/class-mouse#mouse-move. Playwright can’t find this menu option. This is because this context menu is not apart of the page, understandably. I need some way to query that option.

Here is my Playwright test code. I am going to an arbitrary background page “https://www.google.com”. The implementation details of ‘loginWith’ are irrelevant. This custom menu option shows up in the test browser as I showed in the screenshots previously:

import { test, expect } from "../fixtures";
import { goto, loginWith, testUser, VITE_API_DOMAIN } from "../helpers";

test.describe("Context menus", () => {
  test.describe("when the user is logged in", () => {
    test.beforeEach(async ({ page, context, request, extensionId }) => {
      await context.clearCookies();
      await request.delete(`${VITE_API_DOMAIN}/testing/reset`);
      await request.post(`${VITE_API_DOMAIN}/users`, {
        data: testUser,
      });
      await goto(page, extensionId);
    });

    test("it shows the context menu", async ({
      page,
    }) => {
      await loginWith(page, testUser.email, testUser.password);

      await page.goto("https://www.google.com");

      const privacyButton = page.getByText("Privacy");
      await privacyButton.selectText();
      await privacyButton.click({ button: "right" });

      const addWordButton = page.getByRole("button", { name: "Add Word" });
      await expect(addWordButton).toBeVisible();
    });

  });
});

Test output:

Running 1 test using 1 worker
  1) [chromium] › tests/e2e/ContextMenu/context_menu.spec.ts:15:5 › Context menus › when the user is logged in › it shows the context menu when the user is logged in 

    Error: Timed out 5000ms waiting for expect(locator).toBeVisible()

    Locator: getByRole('button', { name: 'Add Word' })
    Expected: visible
    Received: <element(s) not found>
    Call log:
      - expect.toBeVisible with timeout 5000ms
      - waiting for getByRole('button', { name: 'Add Word' })


      25 |
      26 |       const addWordButton = page.getByRole("button", { name: "Add Word" });
    > 27 |       await expect(addWordButton).toBeVisible();
         |                                   ^
      28 |     });

This other post mentions wanting to interact with the browser’s default context menu but this user did not add a custom menu option so it is not applicable to my situation: Right mouse click and selecting the appropriate item using Playwright.

This particular post mentions interacting with in-application custom context menus which I do not have. My context menu is apart of the browser’s context menu: How to Identify that the Right Click Menu Is Available and You Can Open in New Tab Without Screenshots.

If you want something close to a very simple similar repro, setup a basic playwright project as shown here to try and click any of the default Chrome browser context menu options like “Reload”, “Inspect”, etc: https://playwright.dev/docs/intro. If one is able to select these default Chrome context menu options, the same should be applicable for my custom ‘Add Word’ context menu option.

How to encrypt and decrypt a file using gpg command using assymetric key? [duplicate]

For my laravel application, I need the gpg command to do encryption and decryption of CSV file using asymmetric key.

In my laravel application, I am already using symmetric key encryption and decryption using gpg command. But

Below is the command I used for encryption using symmetric key

exec("echo {$key} | gpg --passphrase-fd 0 --batch --yes -o {$filename['enc_name']} --armor --symmetric {$filename['name']}", $output, $retval);

Below is the command I used for decryption using symmetric key

 $fd = [ 0 => [ 'pipe', 'r'], 1 => [ 'pipe' , 'w' ] ];
proc_open("gpg --passphrase-fd 0 --batch -o $target -d $filename",
            $fd,
            $pipes,
            Storage::disk('rg-local')->path( '' )
        );

if( is_resource($process) )
        {
            fwrite( $pipes[0], $passphrase );
            fclose( $pipes[0] );

            $result = stream_get_contents( $pipes[1] );
            fclose( $pipes[1] );
            $retval = proc_close( $process );
            if($retval > 0)
            {
                Log::alert("Failed to decrypt file $filename. ProcOpen returned $retval. Error: $result");
                throw new Exception("Failed to decrypt file $filename. ProcOpen returned $retval. Error: $result");
            }
        }

For asymmetric encryption/decryption, I removed ‘–symmetric’ option from the above encryption command. But I got error as below (in laravel tinker)

>  fwrite( $pipes[0], $passphrase );
gpg: AES256.CFB encrypted data
= 5888

> fclose( $pipes[0] );gpg: encrypted with 1 passphrase
gpg: decryption failed: Bad session key

Core PHP cURL – header origin pass null value

Payment Gateway Integration To access the URL, I’m using PHP’s cURL function. Please refer to the code.

The code answer is 200 OK. However, it is not the intended answer. I reviewed the request headers in the developer tool and found that the Origin value is null.

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://test.sbiepay.sbi/secure/AggregatorHostedListener");
curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
    'EncryptTrans' => $EncryptTrans,
    'merchIdVal' => $sbimerchantid
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Origin: https://daa12.in',
    'Referer: https://daa12.in/',
    'Content-Type: application/x-www-form-urlencoded',
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
]);


curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
if ($response === false) {
    echo "cURL Error: " . curl_error($ch);
}
else
{
    echo $response;
}
curl_close($ch);

Please provide the solution for this issue. If the proper URL is passed by the origin variable, I will receive the anticipated response. I don’t know; the origin value is null.

This is the request headers value

    accept:      text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
accept-encoding: gzip, deflate, br, zstd
accept-language: en-US,en;q=0.9,ar;q=0.8
cache-control:  max-age=0
connection:    keep-alive
content-length:  318
content-type:    application/x-www-form-urlencoded
cookie:    PHPSESSID=07s6sja3dqlllmrl9n82kq46ob
host:   daa12.in
origin: null

Laravel Auth::attempt() error: “Unknown column ‘password'” when using a custom password field

I’m working on a Laravel project to migrate the project from codeigniter to laravel so i’m using a multi guard authentication and custom admin user table named tbl_admin_user, where both email and password column is named admin_user_email_id and admin_user_password instead of the default password.

But currently i’m facing this error – Where the field name is not mapping i guess plus I don’t know why it’s even passing the update query and the hashed password is not similar with the password which i have in my DB.
The error highlights on the attempt() method..
Error

I have a custom guard admin and a custom Office model that extends Authenticatable. Here’s what I’ve done:
Model


namespace AppModels;

use IlluminateSupportFacadesHash;
use IlluminateNotificationsNotifiable;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateFoundationAuthUser as Authenticatable;

class Office extends Authenticatable
{

    use HasFactory, Notifiable;

    protected $table = 'tbl_admin_user';
    protected $primaryKey = 'admin_user_id';
    public $incrementing = true;
    public $keyType = 'int';

    protected $fillable = [
        // other column names
        'admin_user_email_id',
        'admin_user_password',
       // other column names
        'admin_updated_on',
        'admin_created_on',
    ];

    // Use customized field name
    public function getAuthIdentifierName() {
        return 'admin_user_email_id';
    }
    
    // Gets the hashed password
    public function getAuthPassword() {
        return $this->admin_user_password;
    }


    public $timestamps = false;

}

Login function from the controller

// Begin::Authenticate login
    public function authenticateOfficeLogin(Request $request) {
        // validate
        $validate = $request->validate([
            'admin_user_email_id' => 'required|email',
            'admin_user_password' => 'required'
        ]);
        
        // Store credentials
        $credentials = [
           'admin_user_email_id' => $validate['admin_user_email_id'],
           'password' => $validate['admin_user_password'],
           'admin_user_status' => 1,
        ];
        
        $user = Office::where('admin_user_email_id', $request->admin_user_email_id)->first(); // Gets the matching data

       
        // Check if user is authenticated
        if($user) {
            $authenticate = Auth::guard('admin')->attempt($credentials); // Here i got the error
            // if authenticated
                if($authenticate) {
                    return redirect()->route('office.dashboard')->with('success','Logged In Successfully!'); // redirect to the dashboard
                }
            }
        }
    // End::Authenticate login

What i’ve tried :
Cleared configuration and route cache using php artisan config:clear, route:clear, and cache:clear and even tried optimize:clear.

Added Log::info() statements before the Auth::attempt() call, but nothing gets logged.

Verified that the provided password matches the hashed password using Hash::check() inside dd() before the attempt() call, and it returned true for now.

List of recipes with ability to sort them by date. Livewire 3

I need to create a logic for my page with filtered recipes with ability to sort them by date

Current code

RecipeController gives me $recipes it is a collection with filtered recipes (params for filter are from URL):

class RecipeController extends Controller
{
    public function index(RecipeFilterRequest $request)
    {
        // ...after filtration logic => $recipes

        return view('recipes.recipes', compact('recipes'));
    }
}

And then in recipes/recipes.blade.php:

@foreach($recipes as $recipe)
    <x-recipe-card :recipe="$recipe"/>
@endforeach

components/recipe-card.blade.php is basically a card with recipe info

What I want to achieve:

I need to create a logic for dropdown filter that will sort list of filtered recipes by date added

It looks like this: https://i.ibb.co/wrrffZVK/sort-dropdown.jpg

My suggestion:

Make an extra livewire component livewire/recipes-list.blade.php(RecipesList.php) and in recipes.blade.php use this livewire component for the list of (filtered in RecipeController) recipes .

and I’ll basically do everything in this order:

RecipeController =(passing $recipes)=> recipes.blade.php =(passing $recipes to livewire component)=> livewire/recipes-list.blade.php

and in livewire/recipes-list.blade.php I’ll add logic for this dropdown

What do you think?

Has anyone done anything similar/exactly the same?

Would be grateful for some advices

Concerns when migrating from PHP 5.6 to 8.4 [closed]

I am currently using PEAR and considering migrating from PHP 5.6 to PHP 8.4 for our current site.
Does the latest stable version of PEAR (1.10.16) support PHP8.4?
Or should I discontinue PEAR and move to Composer?

I’d like to avoid major renovations as much as possible.

Package in use
HTTP_Request2, OS_Guess, Net_URL2