webpush not wokring in chrome on localhost - node.js

I'm building a website with node.js and I' m making some push notifications and it doesn' t send them on chrome version 109.0.5414.120 . I tried running it on opera gx and it worked there. I have to use chrome because its for a school project and all my teachers use chrome and the don't want to download new programms
the code;
app.js
const express = require("express")
const webpush = require('web-push')
const app = express()
app.use(express.json());
const path = require("path")
app.use(express.static(path.join(__dirname, 'client')))
const publicKey = "BL2QpTNn-CZARUqJhm4tDPPful3TMIjugZdyi1WNIcaps21w7KJFy4cjilMNk-NbeEIwWVA5ddCXpOStd6RTuXA"
const privateKey = "dWcFCcnNS-uBYS6GISodobLXht-9KpOQmeHh1h89T7w"
webpush.setVapidDetails("mailto:thdegroote18#gmail.com", publicKey, privateKey)
app.post("/subscribe", async (req, res) => {
try {
// Subscription Details From the client side , We would get back to this
const subscription = req.body;
subscribers.push(subscription);
// Save the new subscrber to the subscribers file
fs.writeFileSync("./subscribers.json", JSON.stringify(subscribers));
res.status(201).send("Subscription Saved");
} catch (error) {
console.error(error);
}
});
const subscribers = require("./subscribers.json")
const fs = require("fs")
async function sendPushNotificaiton() {
for (let i = 0; i < subscribers.length; i++) {
const subscription = subscribers[i];
//Notification Payload, this could contain more information about the notification
const payload = {
title: "Push Test",
body: " Push Notification Message",
icon: "https://blog.mensaiah.com/assets/round_logo.png",
};
//Pass object into sendNotification
await webpush.sendNotification(subscription, JSON.stringify(payload));
}
}
//Send Notification Every Minute
const durationInMillisecond = 60 * 10000
setInterval(sendPushNotificaiton,durationInMillisecond);
const port = 1999
app.listen(port, () => {
console.log(`server started on port ${port}`)
})
client.js
const publicVapidKey = "BL2QpTNn-CZARUqJhm4tDPPful3TMIjugZdyi1WNIcaps21w7KJFy4cjilMNk-NbeEIwWVA5ddCXpOStd6RTuXA";
async function subscribeToPush() {
console.log("Registering service worker...");
const register = await navigator.serviceWorker.register("/worker.js", {
scope: "/"
});
console.log("Service Worker Registered...");
console.log("Registering Push...");
const subscription = await register.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
});
console.log("Push Registered...");
console.log("Subscribing for Push ...");
await fetch("http://localhost:1999/subscribe", {
method: "POST",
body: JSON.stringify(subscription),
headers: {
"Content-Type":"application/json"
}
});
}
function urlBase64ToUint8Array(base64String) {
const padding = "=".repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
if ('serviceWorker' in navigator) {
subscribeToPush().catch(console.log);
}
worker.js
self.addEventListener("push", e => {
// Data from service
const data = e.data.json();
console.log("Push Recieved...");
self.registration.showNotification(data.title, {
body: data.body,
icon: data.icon,
});
});

Related

An error when trying to post a photo on instagram using instagram-private-api

I've tried to post a photo on instagram, but I've got an Bad Request error. Is that package fault or mine?
Code:
// modules
const config = require("./config.json");
const createPost = require("./canvas");
const fs = require('fs');
// db
const { QuickDB } = require('quick.db');
const db = new QuickDB();
// instagram
const { IgApiClient } = require('instagram-private-api');
const { sample } = require('lodash');
const ig = new IgApiClient();
ig.state.generateDevice(config.instagramUsername);
// tellonym
const Tellonym = require('tellonym-api');
const client = new Tellonym.login(config.tellonymToken);
// variabls
let tells = [];
// main code
setInterval(async () => {
client.getQuestions(20).then(response => {
response.forEach(async tell => {
if (tell.type === 'tell')
{
tells.push(tell.tell);
if(JSON.parse(JSON.stringify(await db.get('tells'))).strings[0].includes(tell.tell)) return;
await createPost(tell.tell);
await ig.simulate.preLoginFlow();
const loggedInUser = await ig.account.login(config.instagramUsername, config.instagramPassword);
process.nextTick(async () => await ig.simulate.postLoginFlow());
const post = await ig.publish.photo(
{
"file": fs.readFileSync("./output.png")
}
);console.log(post)
}
});
db.set("tells", {strings: [tells]});
});
}, 0.1 * 1000 * 60);
Error:
C:\Users\PC\Desktop\spotted\node_modules\instagram-private-api\dist\core\request.js:126
return new errors_1.IgResponseError(response);
^
IgResponseError: POST /rupload_igphoto/1671729786445_0_4886961932 -
400 Bad Request;
at Request.handleResponseError (C:\Users\PC\Desktop\spotted\node_modules\instagram-private-api\dist\core\request.js:126:16)
at Request.send (C:\Users\PC\Desktop\spotted\node_modules\instagram-private-api\dist\core\request.js:54:28)
at async UploadRepository.photo (C:\Users\PC\Desktop\spotted\node_modules\instagram-private-api\dist\repositories\upload.repository.js:18:26)
at async PublishService.photo (C:\Users\PC\Desktop\spotted\node_modules\instagram-private-api\dist\services\publish.service.js:80:31)
at async C:\Users\PC\Desktop\spotted\index.js:38:30
Node.js v19.2.0

Azure: INFO - Waiting for response to warmup request for container ... Elapsed time = x sec

My app fails on prod and can't find a way how to fix. It works on another environments.
Some logs from the console:
2022-08-22T23:56:05.760Z INFO - Waiting for response to warmup request for container projectprod-fe_0_fd84e. Elapsed time = [225.2643051] sec
2022-08-22T23:56:35.818Z ERROR - Container projectprodfe_0_fd84e for site teamgullitpreview-fe did not start within expected time limit. Elapsed time = 255.322965 sec
It is next.js app and I create middlewares for it.
const next = require('next');
const { parse } = require('url');
nextMiddleware
async function nextMiddleware(dev = false) {
const app = next({ dev });
const handle = app.getRequestHandler();
await app.prepare();
return function nextHandler(req, res) {
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
};
}
redirectMiddleware
const path = require('path');
const fs = require('fs');
const staticFiles = ['_next', '/', 'images', 'api'];
const getRedirect = async (srcPath) => {
try {
const url = `${process.env.NEXT_PUBLIC_apiUrl}/redirect?path=${srcPath}`;
const response = await fetch(url);
const json = await response.json();
return json;
} catch (e) {
throw new Error(e);
}
};
function redirecter(pathname) {
return new Promise((resolve, reject) => {
const pathParts = pathname.split('/');
if (staticFiles.indexOf(pathParts[1]) > -1) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
const possibleFile = `${path.resolve(
__dirname,
'../../public',
)}${pathname}`;
if (fs.existsSync(possibleFile)) {
resolve({
shouldRedirect: false,
redirectData: {},
});
} else {
getRedirect(pathname)
.then((result) => {
resolve({
shouldRedirect: true,
redirectData: result,
});
})
.catch((e) => {
reject(e);
});
}
}
});
}
async function redirectMiddleware(req, res, next) {
const parsedUrl = parse(req.url, true);
const { pathname } = parsedUrl;
try {
const { shouldRedirect, redirectData } = await redirecter(pathname);
if (shouldRedirect && redirectData.destination) {
const redirectUri = `${process.env.NEXT_PUBLIC_hostname}${
redirectData.type ? redirectData.type : ''
}${redirectData.destination}`;
res.writeHead(redirectData.statusCode[0], {
Location: redirectUri,
});
res.end();
}
} catch (e) {
next();
} finally {
next();
}
}
What I do wrong in this file or whenever?
const http = require('http');
const express = require('express');
const redirectMiddleware = require('./src/server/redirectMiddleware');
const nextMiddleware = require('./src/server/nextMiddleware');
const port = process.env.PORT || 3000;
async function bootstrap() {
const isDevelopment = process.argv.includes('--dev');
const app = express();
app.use(await redirectMiddleware);
app.use(await nextMiddleware(isDevelopment));
const server = http.createServer(app);
server.listen(port, (err) => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
}
bootstrap().catch((err) => {
console.error('something went wrong booting up the server.');
console.error(err);
process.exit(1);
});
I have no idea what's wrong and how to debugg it. Is anyone who experienced it before?

RefreshToken not present in tokenSET

I am trying to connect with the api hubstaff to which I have set up my authentication using auth0 and express as my backend. To know about the info about the logged in user I need to send the token object via the API.
By some research I have gotten to this point:
const {
Issuer,
TokenSet
} = require('openid-client');
const fs = require('fs');
const jose = require('jose');
// constants
const ISSUER_EXPIRE_DURATION = 7 * 24 * 60 * 60; // 1 week
const ACCESS_TOKEN_EXPIRATION_FUZZ = 30; // 30 seconds
const ISSUER_DISCOVERY_URL = 'https://account.hubstaff.com';
// API URl with trailing slash
const API_BASE_URL = 'https://api.hubstaff.com/';
let state = {
api_base_url: API_BASE_URL,
issuer_url: ISSUER_DISCOVERY_URL,
issuer: {}, // The issuer discovered configuration
issuer_expires_at: 0,
token: {},
};
let client;
function loadState() {
return fs.readFileSync('./configState.json', 'utf8');
}
function saveState() {
fs.writeFileSync('./configState.json', JSON.stringify(state, null, 2), 'utf8');
console.log('State saved');
}
function unixTimeNow() {
return Date.now() / 1000;
}
async function checkToken() {
//console.log('state.token.access_token', state.token.access_token);
if (!state.token.access_token || state.token.expires_at < (unixTimeNow() + ACCESS_TOKEN_EXPIRATION_FUZZ)) {
// console.log('Refresh token');
state.token = await client ? .refresh(state.token);
// console.log('Token refreshed');
saveState();
}
}
async function initialize() {
console.log('API Hubstaff API');
let data = loadState();
data = JSON.parse(data);
if (data.issuer) {
state.issuer = new Issuer(data.issuer);
state.issuer_expires_at = data.issuer_expires_at;
}
if (data.token) {
state.token = new TokenSet(data.token);
}
if (data.issuer_url) {
state.issuer_url = data.issuer_url;
}
if (data.api_base_url) {
state.api_base_url = data.api_base_url;
}
if (!state.issuer_expires_at || state.issuer_expires_at < unixTimeNow()) {
console.log('Discovering');
state.issuer = await Issuer.discover(state.issuer_url);
state.issuer_expires_at = unixTimeNow() + ISSUER_EXPIRE_DURATION;
console.log(state.issuer);
}
client = new state.issuer.Client({
// For personal access token we can use PAT/PAT.
// This is only needed because the library requires a client_id where as the API endpoint does not require it
client_id: 'Z',
client_secret: 'J',
});
saveState();
console.log('API Hubstaff initialized');
}
async function request(url, options) {
await checkToken();
let fullUrl = state.api_base_url + url;
return client ? .requestResource(fullUrl, state.token, options);
}
function tokenDetails() {
let ret = {};
if (state.token.access_token) {
ret.access_token = jose.JWT.decode(state.token.access_token);
}
if (state.token.refresh_token) {
ret.refresh_token = jose.JWT.decode(state.token.refresh_token);
}
return ret;
}
module.exports = {
initialize,
checkToken,
request,
tokenDetails
};
// COntroller
const { response } = require('express')
const api = require('../util/hubstaffConnect.util');
const testConnected = require('../util/testhubstaff.util');
const usersGet = async (req, res = response) => {
await api.initialize();
const response = await api.request('v2/organizations',{
method: 'GET',
json: true,
});
console.log('response', response);
if(response != null){
const body = JSON.parse(response);
res.json({
organizations: body.organizations || []
});
}
};
Although when I go to the address localhost:8080/oauth/api/organizations I ran into an error:
I do realise this is regarding missing tokens which won't let me get the user's information.

Node run multiple instances and close only requested instance

I am using xvbf in node application to run a chrome client for capturing web site screens in background. From a web page i am passing data to my webservice as at the bottom of this code part to START_CAPTURE and STOP_CAPTURE.
const puppeteer = require('puppeteer');
const Xvfb = require('xvfb');
var exec = require('child_process').exec;
const os = require('os');
const homedir = os.homedir();
const platform = os.platform();
const http = require('http');
const StringDecoder = require('string_decoder').StringDecoder;
const http_port = 8000;
const ffmpegServer = config.ffmpegServer + ":" + config.ffmpegServerPort;
var xvfb = new Xvfb({
silent: true,
xvfb_args: ["-screen", "0", "1280x800x24", "-ac", "-nolisten", "tcp", "-dpi", "96", "+extension", "RANDR"]
});
var action = "";
var width = 1280;
var height = 720;
var options = {
headless: false,
args: [
'--enable-usermedia-screen-capturing',
'--allow-http-screen-capture',
'--load-extension=' + __dirname,
'--disable-extensions-except=' + __dirname,
'--disable-infobars',
'--start-fullscreen',
'--app=https://www.google.com/'`
],
}
options.executablePath = "/usr/bin/google-chrome"
async function main() {
try{
if(platform == "linux"){
xvfb.startSync()
}
var exportname = 'video.webm'
var url = 'https://www.google.com/';
var duration = 30;
const browser = await puppeteer.launch(options)
const pages = await browser.pages()
const page = pages[0]
page.on('console', msg => {
var m = msg.text();
console.log('PAGE LOG:', m)
});
await page._client.send('Emulation.clearDeviceMetricsOverride')
await page.goto(url, {waitUntil: 'networkidle2'})
await page.setBypassCSP(true);
if(duration > 0){
await page.waitFor((duration * 1000))
}else{
while(action!="STOP_CAPTURE"){
try {
await page.waitForSelector('[class^=modal] > [class^=content] > button[description="Logs you out"]', {
timeout: 1000
});
} catch (err) {
// Do nothing
}
}
}
await page.close()
await browser.close()
if(platform == "linux"){
xvfb.stopSync()
}
fs.unlinkSync(homedir + "/video.webm");
}catch(err) {
console.log(err)
}
}
// Instantiate the HTTP server.
const httpServer = http.createServer((req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
if (req.method == 'POST') {
var jsonString = '';
var buffers = [];
req.on('data', function (chunk) {
buffers.push(chunk);
});
req.on('error', (err) => {
// This prints the error message and stack trace to `stderr`.
console.log("Error: %s \n" + err.stack);
});
req.on('end', function () {
try {
jsonString = JSON.parse(Buffer.concat(buffers).toString());
var action = jsonString.markers[0]['action'];
if(action=="START_CAPTURE"){
main();
}
}
catch(e) {
jsonString = JSON.parse(JSON.stringify(Buffer.concat(buffers).toString()));
console.log('\nError \n ' + JSON.stringify(jsonString));
}
});
}
res.end();
console.log('Response ended here. \n ');
});
httpServer.listen(http_port, () => {
console.log("Web server is listening on port %s \n", http_port);
});
This is how it works.
I am clicking a button (START_CAPTURE) from my web site to start capturing. Then capture start. Then i am clicking a button (STOP_CAPTURE) to stop capturing.
everything is working fine. If i do like this.
But if i click START_CAPTURE using two different browsers, then i clicked on STOP_CAPTURE button from any browser window, both instances are getting stop.
I know it is happened because of this lines.
while(action!="STOP_CAPTURE"){
try {
await page.waitForSelector('[class^=modal] > [class^=content] > button[description="Logs you out"]', {
timeout: 1000
});
} catch (err) {
// Do nothing
}
}
Is there anyway to stop only requested instance ? How can i achieve it ?

App refused to connect (NodeJs & Express)

I've created an app in the Partners panel, and I followed this documentation (using Nodejs and Express).
I can get the JSON format for the products' object without any problem. However, when I add to the scopes variable "read_price_rules" I get this error message: "express-example-app refused to connect."
Is this issue caused by the app's permissions?
My app can: Read products, variants, and collections.
Here is the index.js file:
const dotenv = require('dotenv').config();
const express = require('express');
const app = express();
const crypto = require('crypto');
const cookie = require('cookie');
const nonce = require('nonce')();
const querystring = require('querystring');
const request = require('request-promise');
const apiKey = process.env.SHOPIFY_API_KEY;
const apiSecret = process.env.SHOPIFY_API_SECRET;
const scopes = 'read_products,read_price_rules';
const forwardingAddress = "https://53b16008.ngrok.io";
app.listen(3000, () => {
console.log('Example app listening on port 3000!');
});
app.get('/shopify', (req, res) => {
const shop = req.query.shop;
if (shop) {
const state = nonce();
const redirectUri = forwardingAddress + '/shopify/callback';
const installUrl = 'https://' + shop + '/admin/oauth/authorize?client_id=' + apiKey + '&scope=' + scopes + '&state=' + state + '&redirect_uri=' + redirectUri;
res.cookie('state', state);
res.redirect(installUrl);
}
else { return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request'); }
});
app.get('/shopify/callback', (req, res) => {
const { shop, hmac, code, state } = req.query;
const stateCookie = cookie.parse(req.headers.cookie).state;
if (state !== stateCookie) { return res.status(403).send('Request origin cannot be verified'); }
if (shop && hmac && code) {
// DONE: Validate request is from Shopify
const map = Object.assign({}, req.query);
delete map['signature'];
delete map['hmac'];
const message = querystring.stringify(map);
const providedHmac = Buffer.from(hmac, 'utf-8');
const generatedHash = Buffer.from(crypto.createHmac('sha256', apiSecret).update(message).digest('hex'), 'utf-8');
let hashEquals = false;
try { hashEquals = crypto.timingSafeEqual(generatedHash, providedHmac) }
catch (e) { hashEquals = false; };
if (!hashEquals) { return res.status(400).send('HMAC validation failed'); }
// DONE: Exchange temporary code for a permanent access token
const accessTokenRequestUrl = 'https://' + shop + '/admin/oauth/access_token';
const accessTokenPayload = {
client_id: apiKey,
client_secret: apiSecret,
code,
};
request.post(accessTokenRequestUrl, { json: accessTokenPayload })
.then((accessTokenResponse) => {
const accessToken = accessTokenResponse.access_token;
// DONE: Use access token to make API call to 'shop' endpoint
const shopRequestUrl = 'https://' + shop + '/admin/api/2019-04/discount_codes/lookup.json?code=20OFF';
const shopRequestHeaders = { 'X-Shopify-Access-Token': accessToken, };
request.get(shopRequestUrl, { headers: shopRequestHeaders })
.then((shopResponse) => {
res.status(200).end(shopResponse);
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
} else {
res.status(400).send('Required parameters missing');
}
});
I Just had to reinstall the app after adding an extra scope in the index.js file.

Resources