Local Safari extension can't access CSS file - reactjs

I recently converted my Chrome extension to a Safari extension using the Apple Conversion tool (XCode CLI). The extension is developed with ReactJS and SaSS. It works very well on Google Chrome but when I try it on Safari after converting it, the local extension works but the CSS file that handles the extension is not applied.
There are no errors during the conversion but the Safari developer tool indicates several errors :
console tab : Failed to load resource: You are not allowed to access the required resource.
network tab : An error occurred while trying to load the resource and the resource was requested in an insecure manner.
In the extension, we isolate CSS using iframe :
/*global chrome*/
/* src/content.js */
import React from 'react';
import ReactDOM from 'react-dom';
import Frame, { FrameContextConsumer }from 'react-frame-component';
import "./content.css";
class Main extends React.Component {
render() {
return (
<Frame head={[<link type="text/css" rel="stylesheet" href={chrome.runtime.getURL("/static/css/content.css")} ></link>]}>
<FrameContextConsumer>
{
// Callback is invoked with iframe's window and document instances
({document, window}) => {
// Render Children
return (
<div className={'my-extension'}>
<h1>Hello world - My first Extension</h1>
</div>
)
}
}
</FrameContextConsumer>
</Frame>
)
}
}
Here is the manifest.json file:
{
"short_name": "My Extension",
"name": "My Extension",
"version": "1.0",
"manifest_version": 3,
"icons": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"action": {
"default_icon": {
"16": "icon16.png",
"48": "icon48.png",
"128": "icon128.png"
},
"default_title": ""
},
"background": {
"service_worker": "background.js"
},
"content_scripts" : [
{
"matches": ["<all_urls>"],
"css": ["/css/root.css"],
"js": ["/static/js/content.js"]
}
],
"permissions": [
"activeTab",
"scripting",
"storage"
],
"host_permissions": ["https://www.google.com/*"],
"web_accessible_resources": [{
"resources": [
"/static/css/content.css",
"/static/media/*"
],
"matches": ["<all_urls>"]
}]
}
After many attempts, I did not understand the exact origin of the problem and I do not know how to solve it. Do you have any suggestions ?

Related

google chrome extension not injecting html to the page

I am creating a chrome extension. It injects a chat to the page of the user choice.
It works on all websites I checked but does not on a specific one.
I have a component called , when I click the button to inject the chat in the Popup.html it sends console.log to the page, from that component, but the component is not being rendered for some reason.
That's the page https://p.priority-connect.online/webui/P3A3E/
I tried to render it on another websites and it worked well.
Created console.log inside the component and received result inside the website console but not a rendered component.
that's my manifest file
{
"manifest_version": 3,
"name": "WhatsApp Chat",
"description": "A chrome extension boilerplate built with React 17, Webpack 5, and Webpack Dev Server 4",
"options_page": "options.html",
"background": {
"service_worker": "background.bundle.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": "icon-34.png"
},
"icons": {
"128": "icon-128.png"
},
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*",
"<all_urls>"
],
"js": [
"contentScript.bundle.js"
],
"css": [
"content.styles.css"
]
}
],
"devtools_page": "devtools.html",
"web_accessible_resources": [
{
"resources": [
"content.styles.css",
"icon-128.png",
"icon-34.png",
"assets/img/*"
],
"matches": [
"<all_urls>"
]
}
]
}

How can i append react index.html file when i click a chrome extension

I want to make a chrome extension using react. The problem I face I can't load the index.html file that is inside the public directory. My goal is when I click my chrome extension then the index.html file append inside the existing web page
This is my manifest.json code :
{
"name": "Demo Exe",
"description": "The demo chrome extension",
"version": "1.0",
"manifest_version": 2,
"permission": ["active"],
"permissions": ["storage", "activeTab", "scripting"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["./index.js"]
}
]
}

String contains an invalid character when running gatsby develop

I'm building a gatsby web app, I was working with wsl on windows, and it was working well, I even deployed it to a github pages repository, which worked fine, but then I decided I didn't need to use wsl anymore, so I uninstalled it, cloned the git repository and tried to build the app using gatsby develop but in the localhost page it shows this error with no more context:
Unhandled Runtime Error.
One unhandled runtime error found in your files. See the list below to fix it:
Unknown Runtime Error
String contains an invalid character
No codeFrame could be generated
Which isn't particularly useful.
Then, by running the gh-pages command to deploy my page to a github pages repository, I get this error:
ERROR
Page data from page-data.json for the failed page "/": {
"componentChunkName": "component---src-pages-index-js",
"path": "/",
"result": {
"data": {
"allFile": {
"nodes": [
{
"name": "1_corazon-de-maple",
"id": "ac582d47-3543-54cd-83b1-9366ca594fe3",
"childImageSharp": {
"gatsbyImageData": {
"layout": "constrained",
"backgroundColor": "#f8e8d8",
"images": {
"fallback": {
"src": "/static/9acd54f4f5e8efa9b11549c85e00ea4f/f76e2/1_corazon-de-maple.png",
"srcSet": "/static/9acd54f4f5e8efa9b11549c85e00ea4f/2fe1e/1_corazon-de-maple.png 480w,\n/static/9acd54f4f5e8efa9b11549c85e00ea4f/d1fbd/1_corazon-de-maple.png
961w,\n/static/9acd54f4f5e8efa9b11549c85e00ea4f/f76e2/1_corazon-de-maple.png 1921w",
"sizes": "(min-width: 1921px) 1921px, 100vw"
},
"sources": [
{
"srcSet": "/static/9acd54f4f5e8efa9b11549c85e00ea4f/3a3a2/1_corazon-de-maple.webp 480w,\n/static/9acd54f4f5e8efa9b11549c85e00ea4f/e58ca/1_corazon-de-maple.webp
961w,\n/static/9acd54f4f5e8efa9b11549c85e00ea4f/2d899/1_corazon-de-maple.webp 1921w",
"type": "image/webp",
"sizes": "(min-width: 1921px) 1921px, 100vw"
}
]
},
"width": 1921,
"height": 1081
}
}
},
{
"name": "2_appartar",
"id": "12e5156f-1297-5068-a800-2b063db9bf20",
"childImageSharp": {
"gatsbyImageData": {
"layout": "constrained",
"backgroundColor": "#f8f8f8",
"images": {
"fallback": {
"src": "/static/86855c6fbdba7e8237ff47290ac1c15f/eb413/2_appartar.png",
"srcSet": "/static/86855c6fbdba7e8237ff47290ac1c15f/a67ed/2_appartar.png 360w,\n/static/86855c6fbdba7e8237ff47290ac1c15f/379bb/2_appartar.png
720w,\n/static/86855c6fbdba7e8237ff47290ac1c15f/eb413/2_appartar.png 1440w",
"sizes": "(min-width: 1440px) 1440px, 100vw"
},
"sources": [
{
"srcSet": "/static/86855c6fbdba7e8237ff47290ac1c15f/28975/2_appartar.webp 360w,\n/static/86855c6fbdba7e8237ff47290ac1c15f/4b463/2_appartar.webp
720w,\n/static/86855c6fbdba7e8237ff47290ac1c15f/3b606/2_appartar.webp 1440w",
"type": "image/webp",
"sizes": "(min-width: 1440px) 1440px, 100vw"
}
]
},
"width": 1440,
"height": 900
}
}
},
{
"name": "3_sipago",
"id": "65960d9a-741b-5ce9-8519-ddca5800e91d",
"childImageSharp": {
"gatsbyImageData": {
"layout": "constrained",
"backgroundColor": "#f8f8f8",
"images": {
"fallback": {
"src": "/static/3ab66ed0d806a8922cb37b7737185c68/87926/3_sipago.png",
"srcSet": "/static/3ab66ed0d806a8922cb37b7737185c68/a3fa1/3_sipago.png 350w,\n/static/3ab66ed0d806a8922cb37b7737185c68/bc3b9/3_sipago.png
700w,\n/static/3ab66ed0d806a8922cb37b7737185c68/87926/3_sipago.png 1400w",
"sizes": "(min-width: 1400px) 1400px, 100vw"
},
"sources": [
{
"srcSet": "/static/3ab66ed0d806a8922cb37b7737185c68/26a00/3_sipago.webp 350w,\n/static/3ab66ed0d806a8922cb37b7737185c68/f23f0/3_sipago.webp
700w,\n/static/3ab66ed0d806a8922cb37b7737185c68/2c2d0/3_sipago.webp 1400w",
"type": "image/webp",
"sizes": "(min-width: 1400px) 1400px, 100vw"
}
]
},
"width": 1400,
"height": 788
}
}
}
]
},
"site": {
"siteMetadata": {
"title": "Raul Meza Montoya | Portfolio"
}
},
"file": {
"id": "df889c4b-9f80-5d5e-af33-55a721c9d098",
"publicURL": "/static/cd0bd82dbb5f2ff0d8d7ae76b84f470c/cv_raul-meza-montoya.pdf"
}
},
"pageContext": {}
},
"staticQueryHashes": [
"1796249492"
]
}
failed Building static HTML for pages - 1.092s
ERROR #95313
Building static HTML failed for path "/"
See our docs page for more info on this error: https://gatsby.dev/debug-html
15 |
16 | module.exports = _defineProperty;
> 17 | module.exports["default"] = module.exports, module.exports.__esModule = true;
I checked the components in my page and it seems disabling a list of svg components fixed the page, but I can't determine why. the UXUIDesign, FrontEnd, and GraphicDesign are all svg components imported like this:
import FrontEnd from "../images/svgs/front-end_sm.svg";
<ul id="specialty-list" className="list inline-list">
<li>
<UXUIDesign className="svg inline-svg svg-icon" />
<p>Diseño UX/UI</p>
</li>
<li>
<FrontEnd className="svg inline-svg svg-icon" />
<p>Desarrollo Front End</p>
</li>
<li>
<GraphicDesign className="svg inline-svg svg-icon" />
<p>Diseño Gráfico</p>
</li>
</ul>
Update:
Transforming the svg from a regular .svg file to a .js using jsx with transform.tools seems to fix the svgs causing an error, not sure what caused it to fail, and gatsby doesn't specify what went wrong.
I think your issue comes because of the way you are importing the SVG. In Gatsby, this will work:
return <div>
<svg>
{/* some SVG magic code here */}
</svg>
</div>
But this won't:
import SomeSvg from '../svg/path/some-svg.svg'
return <div>
<SomeSvg />
</div>
Because by default, webpack won't interpret SVG files as React components. You can follow this detailed answer: Import SVG as a component in Gatsby but basically, you need to use gatsby-plugin-react-svg. After installing it:
{
resolve: 'gatsby-plugin-react-svg',
options: {
rule: {
include: /svgs/
}
}
}
Note 1: just add the folder that contains the SVG. include is a regular expression (that's why is between slashes, /) so just add the folder name
Note 2: the SVG folder must only contain SVG assets, otherwise the compilation may fail
Then, import it like you were doing:
import FrontEnd from "../images/svgs/front-end_sm.svg";
Move site into allFile query or file query
export const query = graphql`
query {
allFile(
filter: { relativeDirectory: { eq: "thumbnails" } }
sort: { fields: name }
) {
nodes {
name
id
childImageSharp {
gatsbyImageData
}
}
site {
siteMetadata {
title
}
}
}
file(name: {eq: "cv_raul-meza-montoya"}) {
id
publicURL
}
}
`

React Webcam component doesn`t work inside chrome extension

I have a problem with React Webcam - https://github.com/mozmorris/react-webcam
In desktop app everything works great - tried it with create-react-app 2.0 recently - web app starts, asks for permission to use camera and when user allows, camera starts, screenshots work, everything is fine.
However when i copy the exact same component inside our chrome extension there is a problem. When user clicks "change profile photo" the extension opens new page:
chrome-extension://ebjbbcedbjkaagbpbkdlhlnbeoehjmgn/page.html#/uploadsnapshot
The Uploadsnapshot component renders fine, no visible errors (nothing in the console), in the html there is the React-Webcam component element:
<video autoplay="" width="132" height="132" class="UploadPhotoSnapshot__webcam__3VOiZ" playsinline=""></video>
But the camera doesn`t start and no "allow / block camera" popup appears.
I searched for solutions, tried adding "audioCapture" and "videoCapture" to permissions in my "manifest.json" as mentioned here:
How to enable camera and microphone in packaged application for Chrome OS or Chrome extension?
It still will not ask for permission to use camera and will not start.
I also tried using different component: https://github.com/mabelanger/react-html5-camera-photo and got error when the component loads:
onCameraError DOMException: Invalid security origin
My component:
import React, {Component} from 'react';
import Webcam from "react-webcam";
import styles from "./UploadPhotoSnapshot.css";
class UploadPhotoSnapshot extends Component {
constructor(props) {
super(props);
this.state = {
activeImg: null,
imagesArr: []
}
}
setRef = webcam => {
this.webcam = webcam;
};
capture = () => {
let shot = this.webcam.getScreenshot();
let newArr = [...this.state.imagesArr];
newArr.unshift(shot);
this.setState({
activeImg: shot,
imagesArr: newArr
});
};
render() {
const videoConstraints = {
width: 132,
height: 132,
facingMode: "user"
};
let imagesPreview = null;
if (this.state.imagesArr.length > 0) {
imagesPreview = (
<div className={styles.webcamArrScroll}>
{this.state.imagesArr.map((image, index) => (
<img className={styles.webcamArrImg} src={image} alt="" key={index} />
))}
</div>
);
}
return (
<div className={styles.webcamDiv}>
<Webcam
audio={false}
height={132}
ref={this.setRef}
screenshotFormat="image/jpeg"
width={132}
videoConstraints={videoConstraints}
className={styles.webcam}
/>
<button className={styles.webcamBtnTakePhoto} onClick={this.capture}>Take a snapshot</button>
<div className={styles.webcamArr}>
{imagesPreview}
</div>
<div className={styles.buttons}>
<button className={styles.buttonText}>Cancel</button>
<button className={styles.buttonSetPhoto} onClick={this.hasFileUploaded}>Set a profile photo</button>
</div>
</div>
);
}
}
export default UploadPhotoSnapshot;
my manifest.json:
{
"manifest_version": 2,
"name": "DEV",
"description": "dev",
"version": "4.0.0",
"content_security_policy": "script-src 'self' 'unsafe-eval' https://ssl.google-analytics.com https://apis.google.com https://www.google-analytics.com; object-src 'self'",
"default_locale": "en",
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "/icons/icon_48.png",
"default_popup": "index.html"
},
"icons": {
"16": "/icons/icon_16.png",
"32": "/icons/icon_32.png",
"48": "/icons/icon_48.png",
"64": "/icons/icon_64.png",
"128": "/icons/icon_128.png"
},
"web_accessible_resources": [
"app/*",
"/images/*",
"favicon.ico"
],
"sandbox": {
"pages": ["page.html"]
},
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Alt+P"
}
}
},
"permissions": [
"tabs",
"storage",
"identity",
"audioCapture",
"videoCapture",
"identity.email"
],
"oauth2": {
"client_id": "12345.apps.googleusercontent.com",
"scopes": [
"email",
"profile",
"https://www.googleapis.com/auth/contacts.readonly"
]
},
"key": "12345"
}
Do i somehow have to invoke the "allow / deny camera" popup inside the Chrome extension component?
Would be very gratefull for any ideas/ help / hint / solutions.
This might be related to this Chromium bug that makes the extension crash (although you don't get exactly the same error).
See a solution for a possible duplicate here: Chrome Extension - getUserMedia throws "NotAllowedError: Failed due to shutdown"
I found the problem and fixed it.
It all came down to "sandbox": {
"pages": ["page.html"]
}, in the manifest.json file. When you use "sandbox", the content security origin is blocking everything. I deleted it and everything is working. Camera, sound recording, screenshots.

WebExtensions: browser.webRequest.onCompleted never fires

I'm using the Firefox WebExtensions API with the following background script
var log = console.log.bind(console)
log('hello world from browser extension')
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/onCompleted
var filter = { urls: '<all_urls>' }
var extraInfoSpec = ['tlsInfo', 'responseHeaders']
browser.webRequest.onCompleted.addListener(function(details){
log(`Woo got a request, here's the details!`, details)
}, filter, extraInfoSpec)
log('Added listener')
After loading the script from about:debugging, I see the following output in DevTools:
hello world from browser extension
I do not see any output- there is no data from browser.webRequest.onCompleted.addListener and there is no 'Added listener' message.
How do I make browser.webRequest.onCompleted work?
For completeness, my manifest.json is below:
{
"manifest_version": 2,
"name": "Test extension",
"version": "1.0",
"description": "Test extension.",
"icons": {
"48": "icons/border-48.png"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"permissions": [
"webRequest",
"webRequestBlocking"
]
}
The webRequest API is only available to background scripts. You seem to using it inside a content script.
urls in var filter = { urls: '<all_urls>' } needs to be be an array ['<all_urls>'].
'tlsInfo' in extraInfoSpec doesn't exist, I don't know where it comes from.
You need to specify an additional <all_urls> permission in your manifest.
script.js
var filter = { urls: ['<all_urls>'] }
var extraInfoSpec = ['responseHeaders']
browser.webRequest.onCompleted.addListener(function(details){
console.log(`Woo got a request, here's the details!`, details)
}, filter, extraInfoSpec)
console.log('Added listener')
manifest.json
{
"manifest_version": 2,
"name": "Test extension",
"version": "1.0",
"description": "Test extension.",
"icons": {
"48": "icons/border-48.png"
},
"background": {
"scripts": ["script.js"]
},
"permissions": [
"webRequest",
"webRequestBlocking",
"<all_urls>"
]
}

Resources