Chrome extension API for filepicker - google-chrome-extension

There is an API for download handling for google chrome:
https://developer.chrome.com/docs/extensions/reference/downloads/
This is great and it works. But I would love to add a listener for whenever a user triggers an <input type="file /> as well. This can be done with some client side script in content_scripts, but I need to do this with the API and not custom logic
There are two APIs that sounds right but only works for ChromeOS: fileBrowserHandler and fileSystemProvider
// WORKS
chrome.downloads.onCreated.addListener((item) => {
alert(1)
})
// Doesn't work
chrome.fileBrowserHandler.onExecute.addListener((id, details) => {
alert(2)
})
// Doesn't work
chrome.fileSystemProvider.onOpenFileRequested.addListener(() => {
alert(3)
})

Related

Node / React Authentication API callback STUMPER

I've been developing for a year and change and this maybe a novice question but I've tried EVERYTHING (~150 hours worth of tries, YIKES) I will post my React Frontend and my Nodejs backend to hopefully get some clarity.
Key notes:
-I am using Auth0 authentication to build an api with a nodeJs server
-Auth0 says to use an https:// call which my localhost:3000 is not. However, everything about AUTH0 works except the API call invoked when a user logs in to redirect them and display their information on their profile. I have only found one solution to this which is a reverse proxy https:// server to make calls (I can stop here if this is the issue lol unless another easier method is out there). Also why would AUTH0 require production https servers to test???
-I have the correct CORS enabled on AUTH0's site and 99% sure NodeJs (I can get a console.log response from my API) and have tried many ways on the front end and backend
to solve.
Help would greatly, greatly, be appreciated.
Code:
function URLChecker() {
// setTimeout(function(){
// console.log("Executed immediately");
if (location.pathname.indexOf('/profile/') === 0) {
//setToken(true);
return true;
}
}
function tokenChanger() {
setToken(true);
console.log("Your token is presented as...", token)
}
useEffect(()=> {
//console.log("url checker is:" + URLChecker());
if(URLChecker() == true){
tokenChanger();
console.log(location)
if (token) {
console.log("token exists");
axios.defaults.headers.get['Access-Control-Allow-Origin'] = 'http://localhost:3000';
axios.get('http://localhost:8080/profile')
.then(res => {
//console.log(res);
console.log(res.data);
}).catch(error => {
console.log(error);
console.log("API for user FAILED")
})
}
app.get('/profile', requiresAuth(), (req, res, next ) => {
console.log(req.oidc.user);
res.header("Access-Control-Allow-Origin", "*");
res.redirect(http://localhost:3000/profile/${((req.oidc.user.nickname))})
});
(res(req.oidc.user) returns a localhost:8080/profile page that is blank with the JSON of the user's information displayed. My next step is to obviously make my frontend call a different API instead of /profile to hit an authentication required api that will return user data, however no matter what I've tried I always get stuck with the same error message. I am so close and don't know whether to stick with AUTH0 to solve this error or going with Google authentication which I hear is nice.
Thank you,
imgur link to error message on my frontend

MSAL 2.0 Redirect User to Login Screen Fast

I use below libraries:
"#azure/msal-browser": "^2.16.0",
"#azure/msal-react": "^1.0.1",
I need to redirect the user to login screen without user being able to see any content. How would I be able to do that?
Currently, I have this:
export default function Main() {
const msalInstance = new PublicClientApplication(msalConfig);
useEffect(() => {
msalInstance
.handleRedirectPromise()
.then((s) => {
if (s === null) msalInstance.loginRedirect(loginRequest); // not logged in
else console.log(s); // logged in
})
.catch((a: any) => {
console.log("err");
console.log(a);
});
}, []);
return <App instance={msalInstance} />;
}
But, it loads the app for a second then does the redirection.
In order to achieve that specific behavior, there are two options:
Delay rendering your app until the user is confirmed to be logged in (they will be redirected to authenticate before you render your app).
Handle this on the server side by redirecting to the login interaction before the app is rendered (which would involve a solution other than msal-react).
Here is some documentation on the MSAL AuthenticationTemplate, which may be of some help in determining what the right way to use MSAL React would be in this case.
As a final note, it's not recommended that you initialize the PublicClientApplication inside a React component. Please review the Getting Started documentation and the react-router-sample for more guidance on how to initialize MSAL in your application.

Passing data from opened window

I've been stuck on this problem for a day now and was wondering if there's a way I could go about this.
client side
Client side is going to be dynamic since it's an app type plugin.
The client side will open up a popup for oAuth purposes. Let's say its domain is www.google.com
I have the popup written like window.open('www.backend.com/api') in ReactJS.
The client button is something like this:
<button onClick={() => iveBeenClicked()}> sync up </button>
and then it runs this function
const iveBeenClicked = (e) => {
e.preventDefault()
const popupWindow = window.open('www.backend.com/api', "_blank")
}
oAuth and backend with ExpressJS
This is the backend which we'll say is www.backend.com/api
router.use("/api", (req, res) => {
if (req.query.code) {
res.send(res.query.code)
} else {
res.redirect(
`www.ApiRouteThatRedirectsWhenComplete.com`
);
}
});
Well I have the code I want, but how can I send that to the client from a different domain? If there's an alternative to window.open() where a user could press accept, please let me know.
So the big question is, how can client receive data from window.open's popup?
Thank you in advance!
#EDIT
So I finally got it thanks to #vishal-bartakke 's suggestion which I realized I implemented it wrong. I'm going to supply it here just in case it will help anyone that comes across this post.
for the ivebeenclicked() function in client side:
const iveBeenClicked = (e) => {
e.preventDefault()
const popupWindow = window.open('www.backend.com/api', "_blank")
//this is the part that was needed to receive the information of success
window.addEventListener('message', (e) => {
if (e.data) {
//do what you need to do with that key
}
})
}
in my expressjs's file:
router.use(['/api/', '/api/page?'], (req, res) => {
if (req.query.token) {
res.sendFile(path.join(__dirname +'/thatHTMLpage.html'))
} else {
res.redirect(`that route that does the oauth`)
}
})
In that html created upon success, I added this code to send in the data
window.onload = function () {
let urlParams = new URLSearchParams(window.location.search);
window.opener.postMessage(urlParams.get("code"), "*");
};
It is quite a messy setup but it works how I want it.
Thanks!
You can use postMessage (check here) to communicate between windows. In child window you can refer parent window as window.opener for posting message and in parent window you have popupWindow for posting

What is the reason for using GET instead of POST in this instance?

I'm walking through the Javascript demos of pg-promise-demo and I have a question about the route /api/users/:name.
Running this locally works, the user is entered into the database, but is there a reason this wouldn't be a POST? Is there some sort of advantage to creating a user in the database using GET?
// index.js
// --------
app.get('/api/users/:name', async (req, res) => {
try {
const data = (req) => {
return db.task('add-user', async (t) => {
const user = await t.users.findByName(req.params.name);
return user || t.users.add(req.params.name);
});
};
} catch (err) {
// do something with error
}
});
For brevity I'll omit the code for t.users.findByName(name) and t.users.add(name) but they use QueryFile to execute a SQL command.
EDIT: Update link to pg-promise-demo.
The reason is explained right at the top of that file:
IMPORTANT:
Do not re-use the HTTP-service part of the code from here!
It is an over-simplified HTTP service with just GET handlers, because:
This demo is to be tested by typing URL-s manually in the browser;
The focus here is on a proper database layer only, not an HTTP service.
I think it is pretty clear that you are not supposed to follow the HTTP implementation of the demo, rather its database layer only. The demo's purpose is to teach you how to organize a database layer in a large application, and not how to develop HTTP services.

Web Share API Fallback

I am implementing the new Web Share API for a site I am working on (https://developers.google.com/web/updates/2016/09/navigator-share). While it is supported by Safari Desktop, iOS Safari, and Android Chrome, it isn't supported by any other browsers. Is there a fallback that I can use for non-supported browsers to be able to share text and a link from my site?
One fallback I use is Blob, see an example in here https://codesandbox.io/s/bold-leaf-imu3w
It uses 'saveAs' library from npm.
const blob = new Blob(['"Name","Value"\r\n"Alice","100"\r\n"Bob","200"'], {
type: "text/csv"
});
saveAs(blob, "file.csv");
Another suggestion is to just show a regular page where the user can select data and copy it
Probably too late now, but as you can see from under Usage section, the line
`.catch((error) => console.log('Error sharing', error));`
provides a way to check for this. So then you can listen for the error, and write out custom sharing buttons if you want that.
Yes you can check.web share API uses navigator.share
if (navigator.share) {
navigator.share({
title: 'harish tech',
text: 'Check out harishtech.com.',
url: 'https://harishtech.com',
})
.then(() => console.log('Successful share'))
.catch((error) => console.log('Error sharing', error));
}else{
// Your fall back code here
}
For more info check out the link share like native app
If it can help, as a fallback in a React project, we built a second component triggering our own modal and used https://github.com/nygardk/react-share:
export const ShareButton = props => {
if (typeof navigator !== "undefined" && typeof navigator.share !== "undefined")
return <ShareButtonNativeModal {...props} />
else
return <ButtonShareModal {...props} />
}

Resources