redirect a request with firefox addon - firefox

Currently I use addon sdk to develop a firefox extension,which can redirect some request without loading them.
For example, a page refer a.js (maybe have something like this <script src='example.com/a.js'>),
then, I want to redirect this request to example2.com/b.js
Now,with nsIContentPolicy I can block example.com/a.js,
But I don't know how to load example2.com/b.js at the time when a.js is blocked.
my codes now look like this:
const { Cc, Ci } = require("chrome");
const xpcom = require("sdk/platform/xpcom");
const { Class } = require("sdk/core/heritage");
exports.gcleaner = Class({
extends: xpcom.Unknown,
interfaces: ["nsIContentPolicy"],
shouldLoad: function (contType, contLoc, reqOrig, ctx, typeGuess, extra) {
//https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentPolicy#shouldLoad()
if (contType === 2) //2 means js
{
var blockReg = new RegExp('example.com/a.js');
if (contLoc['spec'].match(blockReg))
{
return Ci.nsIContentPolicy.REJECT;
};
};
return Ci.nsIContentPolicy.ACCEPT;
},
shouldProcess: function (contType, contLoc, reqOrig, ctx, mimeType, extra) {
return Ci.nsIContentPolicy.ACCEPT;
}
});
let factory = xpcom.Factory({
Component: exports.gcleaner,
description: "hello world",
contract: "#liujiacai.net/gcleaner"
});
var catman = Cc["#mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
catman.addCategoryEntry("content-policy", "speeding.gcleaner", factory.contract, false, true);
Thanks!

I have a sdk module which does this here
https://github.com/jetpack-labs/pathfinder/blob/master/lib/redirect.js

Related

View with MultiValueEncoded returns only one element

My view should return multiple elements, but I always got only one.
I am calling my view with /vm-values/query.
Should I use another gateway endpoint for the MultiValueEncoded view?
To resolve this issue, I used the queryContract function from the class ApiNetworkProvider in the erdjs npm package.
const apiNetworkProvider = new ApiNetworkProvider("https://devnet-api.elrond.com");
const output = await apiNetworkProvider.queryContract({
address: "erd1....",
func: {
toString(): string {
return "myFunc";
}
},
getEncodedArguments() {
return []; // I don't need args
},
});
The returnData is encoded in base64, so I decoded like so:
const decodedData = output.returnData.map(data => Buffer.from(data, "base64").toString());

How to output a file in i18next via custom plugin?

I tried creating a custom plugin to download data from backend using i18next plugin, however, is stuck at data dumping process. I am using NextJS for frontend.
Here is the configuration file for NextJS.
const { i18n } = require('./next-i18next.config.js/index.js')
module.exports = {
reactStrictMode: true,
i18n
}
Here is the next-18next.config.js file content.
const getDefault = ()=>{
return {
parse: data => JSON.parse(data),
addPath: '/locales/{{lng}}/{{ns}}',
}
}
class Backend {
constructor(services, backendOptions, i18nextOptions){
this.init(services,backendOptions,i18nextOptions)
}
init (services,options={},allOptions={}){
this.services = services;
this.options = {...getDefault(),...options};
this.allOptions = allOptions;
}
async read(language, namespace, callback) {
const payloadUrl = this.options.payloadUrl;
this.data = null;
try {
const response = await fetch(payloadUrl);
const payloadData = await response.json();
this.data = payloadData;
}
catch(err){
return callback(err,this.data)
}
this.loadUrl(language,namespace,callback);
}
async loadUrl (language,namespace,callback){
const loadPath = this.options.loadPath;
const url = this.services.interpolator.interpolate(loadPath, { lng: language, ns: namespace});
try {
const response = await fetch(url);
const data = await response.json();
return callback(language,namespace,data)
}
catch(err){
console.log("Error while fetching payload ", err)
callback(err,null)
}
}
save (language, namespace, data) {
console.log(language,namespace,data);
}
create (language, namespace, key, fallbackValue) {
console.log(language,namespace,key,fallbackValue)
}
dumpData(language,namespace,data){
const filePath = this.services.interpolator.interpolate(this.options.addPath, { lng: language, ns: namespace});
// need to find a way to dump the file into the given filePath, (right now
// I cannot find proper way to use fs library)
console.log(filePath, "is the file path")
console.log("data we dumping ", data);
}
}
Backend.type = "backend";
module.exports = Backend;
I am following https://github.com/i18next/i18next-http-backend and have no idea how they are dumping the payload we get from backend to specific folder. I tried doing it manually adding fs library, however we are using NextJS and using fs gives me error Can't resolve 'fs'. How can we dump the data we receive from backend into its required location?
The callback signature is wrong, callback(language,namespace,data) is not correct. The signature should be callback(error, result) => this means you may change it to: callback(null, data)
Additionally, all these are not async functions, plain old callback based functions, like described here: https://www.i18next.com/misc/creating-own-plugins#backend
btw: if you're fetching data from your backend, why do you not simply use i18next-http-backend and adapt the loadPath and or the parse option and/or the request option: https://github.com/i18next/i18next-http-backend#backend-options ?

How do I map the root without overwriting other paths with koa-mount?

I have the following structure...
- static
- dashboard.html
But when I use the following...
mainApp.use(mount('/', async (ctx)=>{
...
ctx.body = await pug.render('index', {
user: userInfo
}, true);
}));
mainApp.use(mount('/static', serve(__dirname+"/static")));
But when I run it returns the pug render and not the html file in the static folder. If I comment out...
// mainApp.use(mount('/', async (ctx)=>{
// ...
// ctx.body = await pug.render('index', {
// user: userInfo
// }, true);
// }));
mainApp.use(mount('/static', serve(__dirname+"/static")));
I can get the static file but now there is nothing rendering at root.
you are using template engine the wrong way; use koa-views:
const views = require('koa-views');
const router = require('#koa/router')();
const Koa = require('koa');
const app = new Koa();
// middleware
app.use(views('./views'), {
map: { html: 'pug' }
}));
// route definitions
router.get('/', list)
app.use(router.routes());
async function list(ctx) {
await ctx.render('list', { posts: posts });
}

Google address autocomplete api in Stenciljs

I am trying to add a search field for an address using google's address autocomplete in a Stenciljs component. There aren't any resources on it.
First you'll need to load the google maps api script, so that you can interact with the global google.maps object. You can either do that by including a script tag, or write something like the following helper function.
const googleApiKey = '...';
export const importMapsApi = async () =>
new Promise<typeof google.maps>((resolve, reject) => {
if ('google' in window) {
return resolve(google.maps);
}
const script = document.createElement('script');
script.onload = () => resolve(google.maps);
script.onerror = reject;
script.src = `https://maps.googleapis.com/maps/api/js?key=${googleApiKey}&libraries=places`;
document.body.appendChild(script);
});
In order to get the TypeScript types for the global google object, you should install #types/googlemaps into your dev-dependencies.
Then you'll need to implement a function that allows you to search for places, e. g.:
export const searchForPlaces = async (input: string, sessionToken: google.maps.places.AutocompleteSessionToken) => {
const maps = await importMapsApi();
const service = new maps.places.AutocompleteService();
return new Promise<google.maps.places.AutocompletePrediction[]>((resolve) =>
service.getPlacePredictions({ input, sessionToken }, (predictions, status) => {
if (status !== maps.places.PlacesServiceStatus.OK) {
return resolve([]);
}
resolve(predictions);
}),
);
};
None of this is specific to Stencil btw. All that is left to do is to use the searchForPlaces function in your component. A very simple example would be something like:
#Component({ tag: 'maps-place-search' })
export class MapsPlaceSearch {
sessionToken: string;
#State()
predictions: google.maps.places.AutocompletePrediction[];
async componentWillLoad() {
const maps = await importMapsApi();
this.sessionToken = new maps.places.AutoCompleteSessionToken();
}
async search = (e: InputEvent) => {
const searchTerm = e.target.value;
if (!searchTerm) {
this.predictions = [];
return;
}
this.predictions = await searchForPlaces(searchTerm, this.sessionToken);
}
render() {
return (
<Fragment>
<input onInput={this.search} />
<ul>
{this.predictions.map(prediction => <li key={prediction.description}>{prediction.description}</li>)}
</ul>
<Fragment>
);
}
}
The place search will give you a placeId for each prediction. That and the session token you can pass on to a maps.places.PlacesService to get the details for the place and auto-fill your form or whatever you're trying to achieve.

Is it possible to get the raw body on a custom made endpoint on strapi?

I'm building a custom endpoint on Strapi. For this endpoint, I need to have the raw body content. Is it possible to obtain it from the ctx variable?
stripe : async(ctx) => {
// Handle the event
const sig = ctx.request.headers['stripe-signature']
let event = null
try {
// ctx.request.body needs to be the original raw body
event = stripe.webhooks.constructEvent(ctx.request.body,sig, endpointSecret)
}catch (e) {
ctx.badRequest(null,e)
return
}
Create a middleware (/config/middleware.js) and update it to the following
module.exports = {
settings: {
cors: {
enabled: true,
},
parser: {
enabled: true,
multipart: true,
includeUnparsed: true,
},
},
};
In the controller (/api/<model>/controllers/<model>.js):
const unparsed = require("koa-body/unparsed.js");
const unparsedBody = ctx.request.body[unparsed];
The official koa-bodyparser package actually does this out of the box. See: https://github.com/koajs/bodyparser#raw-body
Here is a small example:
import Koa from 'koa';
import KoaRouter from '#koa/router';
import koaBodyParser from 'koa-bodyparser';
const app = new Koa();
const router = new KoaRouter();
const stripeCheckout = (ctx, next) => {
const sig = ctx.request.header['stripe-signature'];
let event;
if (!process.env.STRIPE_ENDPOINT_SECRET) {
throw new Error('Missing Stripe endpoint secret.');
}
try {
event = stripe.webhooks.constructEvent(
ctx.request.rawBody,
sig,
endpointSecret: process.env.STRIPE_ENDPOINT_SECRET
);
} catch (err) {
logger('error', err);
ctx.status = 400;
ctx.body = `Webhook Error: ${err.message}`;
return next();
}
// ... do something with the event
if (event.type === 'checkout.session.completed') {
const session = event.data.object;
// ... do something with the checkout session
}
// return a response to acknowledge receipt of the event
ctx.status = 200;
ctx.body = { received: true };
return next();
};
// POST
router.post('/stripe-checkout', stripeCheckout);
app.use(koaBodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(port, () => {
logger('log', `✅ Done! Server is listening on http://localhost:${port}`);
});
I'm not sure to understand your needs.
ctx.request.body contains the original body of your request.
After that if you want to send event as response body you can do this like that.
ctx.body = event;
And a warning in your code. You wrote define a const for event and you assign event withe the result of your strapi webhook. You have to define a let variable.
It actually works by switching on "includingUnparsed" in the request environment configuration (config/environments/development/request.json -> parser.includedUnparsed: true).
You can access the unparsed body using the koa-body built-in feature for that:
Some applications require crytopgraphic verification of request bodies, for example webhooks from slack or stripe. The unparsed body can be accessed if includeUnparsed is true in koa-body's options. When enabled, import the symbol for accessing the request body from unparsed = require('koa-body/unparsed.js'), or define your own accessor using unparsed = Symbol.for('unparsedBody'). Then the unparsed body is available using ctx.request.body[unparsed].
koa-body docs

Resources