Strapi GraphQL API - 405 Method Not Allowed - api

I've just deployed my Strapi API to production following the docs: https://strapi.io/documentation/v3.x/deployment/heroku.html
And by making POST requests from other origins, I get this error:
Since my API works finally on development (localhost to localhost) I presume that the issue is related to CORS, and if it's, that's the cors configuration that I've set on the API:
config/env/production/security.json:
{
"cors": {
"enabled": true,
"origin": "*"
}
}
config/env/production/middleware.js:
module.exports = {
settings: {
cors: {
enabled: true,
origin: "*",
},
},
};

I was added the cors config on the development environment...
In order to change the cors config on the production environment, the above code should be placed on the following path:
config/env/production/security.json
config/env/production/middleware.js

For me it was missing route in api/blog/config/routes.json
{
"method": "POST",
"path": "/blog",
"handler": "blog.create",
"config": {
"policies": []
}
},

In my case, since I use GraphQL for queries I should add /graphql at the end of the production URL as we do for localhost:1337/graphql.

Related

Can you set an Application's Client Secret using a kickstart file? FusionAuth

I am using a kickstart.json file to setup FusionAuth in developer environments. Everything is automated except I still need to manually go and get the client secret from the fusion auth instance.
Is there anyway I can predefine the client secret in the kickstart file so I can pre-configure it in my app?
you should absolutely be able to set the client secret from kickstart.json. Any API call should work from within Kickstart.
https://fusionauth.io/docs/v1/tech/apis/applications#create-an-application indicates you can POST an application including the client secret.
So a kickstart file like this should work:
{
"variables": {
"defaultTenantId": "30663132-6464-6665-3032-326466613934"
},
"apiKeys": [
{
"key": "mykey",
"description": "API key"
}
],
"requests": [
{
"method": "POST",
"url": "/api/application/85a03867-dccf-4882-adde-1a79aeec50df",
"body": {
"application": {
"name": "Pied Piper",
"roles": [
{
"name": "dev"
},
{
"name": "ceo"
},
{
"name": "intern"
}
],
"oauthConfiguration" : {
"clientSecret": "shhh-your-desired-secret"
}
}
}
}
]
}
I haven't tested that, but don't see any reason why it would not work. (Note that 1.37, the most recent version, has an issue with kickstart as documented here: https://github.com/FusionAuth/fusionauth-issues/issues/1816 but that should be fixed soon.)
If this doesn't work for you, please share the error message and a scrubbed kickstart file.

How can Chrome Extension identify browser authentication with a website -- manifest 3?

Locally on my mac book, my chrome extension is trying to identify whether or not my chrome browser is signed into a specific website. I am referencing these docs. However, the cookie data I am getting back for this specific website is the same regardless of whether or not my browser has authenticated with the site. This is what the cookie looks like printed to console:
{
"domain": "some-random-string.ngrok.io",
"hostOnly": true,
"httpOnly": true,
"name": "_the_app_session",
"path": "/",
"sameSite": "unspecified",
"secure": false,
"session": true,
"storeId": "0",
"value": "random sttring"
}
This is the code I am running:
// Attempt
chrome.cookies.getAll(
{"url": "https://some-random-string.ngrok.io", "name": "_the_app_session"},
function(cookies) {
console.log('cookies', cookies)
}
)
// Attempt
chrome.cookies.get({"url": "https://some-random-string.ngrok.io", "name": "_the_app_session"}, function(cookie) {
console.log('cookie', cookie)
});
How can my chrome extension identify whether or not my browser is signed into a specific website?
This is my manifest file:
{
"manifest_version": 3,
"icons": {
"16": "cooking-icon.png",
"128": "cooking-icon.png"
},
"name": "Some app",
"description": "A Chrome extension app",
"version": "0.1.0",
"action": {
"default_title": "App",
"default_popup": "popup.html"
},
"permissions": [
"cookies",
"scripting"
],
"host_permissions": [
"http://*/*",
"https://*/*"
]
}
My work around for this was to create an endpoint in my app which would check whether or not the browser was signed in. Make a GET request to this endpoint:
const authenticated = await fetch('http://random-string.ngrok.io/authenticated', {
mode: 'cors',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include'
});
Based on the response my chrome extension could tell whether or not my browser has signed into the site.

How to deploy Nuxt.js(SSR with Express.js) to Vercel via Gitlab?

I have successfully built my app and only remain step is deploy to the host Vercel via my repo on Gitlab
I use Nuxt.js(SSR type) with server Express.js and Nuxt.js Now Builder to deploy host Vercel via repo Gitlab
This is structure
api/
--| index.js
now.json
nuxt.config.js
In index.js
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const products = require("./routes/product/products");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Import API Routes
app.use(products);
// Export the server middleware
module.exports = {
path: "/api",
handler: app
};
In now.json
{
"version": 2,
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/now-builder",
"config": {
"serverFiles": [
"package.json"
]
}
}
]
}
And in nuxt.config.js
...
serverMiddleware: [
// API middleware
"~/api/index.js"
]
...
According to Vercel documentation, deploying is very easy, just commit and push code to Gitlab to complete
However, i always get error as below
I don't understand why? I don't know what i missed. Please help me and i'm very grateful for the help
narze, thank you for your solution, unfortunately it didn't work for me but pointed me in the right direction.
Here is my working now.json:
{
"version": 2,
"env": {
"ON_VERCEL": "true"
},
"builds": [
{
"src": "api/**/*.js",
"use": "#now/node"
},
{
"src": "nuxt.config.js",
"use": "#nuxtjs/now-builder"
}
],
"routes": [
{ "src": "/api/(.*)", "dest": "api/index.js" },
{ "src": "/api", "dest": "api/index.js" },
{ "src": "/(.*)", "dest": "$1" }
]
}
serverMiddleware in nuxt.config.js
serverMiddleware: isServerlessEnvironment ? [] : [
'~/api/index.js'
],
where isServerlessEnvironment defined on the very top of nuxt.config.js as
const isServerlessEnvironment = process.env.ON_VERCEL=="true"
API files need to be compiled with #now/node.
Routes need to be set up to separate nuxt routes from api routes.
With conditional isServerlessEnvironment in nuxt.config.js it works on local server with yarn dev and vercel server.
Credits to this article: Nuxt.js with an Express.js API server running on Now.sh
Thank you all for being helpful :)
I have similar problem with deploying Nuxt on Vercel with serverMiddleware's which returned 405 (Not Allowed). I solved it using this doc Nuxt Vercel Builder by specifying property serverFiles in vercel.json:
{
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/vercel-builder",
"config": {
"serverFiles": ["server-middleware/**"]
}
}
]
}
If you need to include files in the server lambda that are not built
by webpack or within static/, such as a local module or
serverMiddleware, you may specify them with this option. Each item can
be a glob pattern.
I know it's a bit late now lol. But I wrote an article to demonstrate the whole process to get your app up and running on Vercel. You can find it here.

Loopback Connector REST API

How to create an external API on Loopback?
I want to get the external API data and use it on my loopback application, and also pass the input from my loopback to external API and return result or response.
Loopback has the concept of non-database connectors, including a REST connector. From the docs:
LoopBack supports a number of connectors to backend systems beyond
databases.
These types of connectors often implement specific methods depending
on the underlying system. For example, the REST connector delegates
calls to REST APIs while the Push connector integrates with iOS and
Android push notification services.
If you post details on the API call(s) you want to call then I can add some more specific code samples for you. In the mean time, this is also from the documentation:
datasources.json
MyModel": {
"name": "MyModel",
"connector": "rest",
"debug": false,
"options": {
"headers": {
"accept": "application/json",
"content-type": "application/json"
},
"strictSSL": false
},
"operations": [
{
"template": {
"method": "GET",
"url": "http://maps.googleapis.com/maps/api/geocode/{format=json}",
"query": {
"address": "{street},{city},{zipcode}",
"sensor": "{sensor=false}"
},
"options": {
"strictSSL": true,
"useQuerystring": true
},
"responsePath": "$.results[0].geometry.location"
},
"functions": {
"geocode": ["street", "city", "zipcode"]
}
}
]
}
You could then call this api from code with:
app.dataSources.MyModel.geocode('107 S B St', 'San Mateo', '94401', processResponse);
You gonna need https module for calling external module inside loopback.
Suppose you want to use the external API with any model script file. Let the model name be Customer
Inside your loopback folder. Type this command and install https module.
$npm install https --save
common/models/customer.js
var https = require('https');
Customer.externalApiProcessing = function(number, callback){
var data = "https://rest.xyz.com/api/1";
https.get(
data,
function(res) {
res.on('data', function(data) {
// all done! handle the data as you need to
/*
DO SOME PROCESSING ON THE `DATA` HERE
*/
enter code here
//Finally return the data. the return type should be an object.
callback(null, data);
});
}
).on('error', function(err) {
console.log("Error getting data from the server.");
// handle errors somewhow
callback(err, null);
});
}
//Now registering the method
Customer.remoteMethod(
'extenalApiProcessing',
{
accepts: {arg: 'number', type: 'string', required:true},
returns: {arg: 'myResponse', type: 'object'},
description: "A test for processing on external Api and then sending back the response to /externalApiProcessing route"
}
)
common/models/customer.json
....
....
//Now add this line in the ACL property.
"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "extenalApiProcessing"
}
]
Now explore the api at /api/modelName/extenalApiProcessing
By default its a post method.
For more info. Loopback Remote Methods

oauth2orize redirect_uri issue

I'm attempting to customize the oauth2orize all-grants example for my use. I can run the all-grants as-is and everything works (as you would expect), but when I run my customized version, I always end up with this error:
Error: Unable to issue redirect for OAuth 2.0 transaction
at Object.response [as handle] (C:\Dev\Expy\api\node_modules\oauth2orize\lib\grant\code.js:122:41)
I've been digging into this a bit and it seems there is a property of the txn variable within that function that should be named redirectURI and should be populated with the redirect_uri from the query string of the initial request to the /dialog/authorize page. For some reason this doesn't happen on my example app. Is this caused by an express version difference? That is the biggest difference that I see between the example code and my customizations. The all-grants uses express 2.* and my app will use express 4.*.
If it isn't an express version issue, where should I start looking in my code for the issue?
For reference, this is what I see in my app for the txn object:
txn: {
"transactionID": "evlUd2q4",
"client": { ... },
"req": {
"type": "code",
"clientID": "5C3B4438-433F-11E5-A532-74653C701F13"
},
"user": { ... },
"res": {
"allow": true
}
}
and this is what I see in that same object with the example (note the presence of the redirectURI in req and in the txn itself):
txn: {
"transactionID": "EEcYp3Uj",
"client": { ... },
"redirectURI": "http://localhost:3000/api/userinfo",
"req": {
"type": "code",
"clientID": "abc123",
"redirectURI": "http://localhost:3000/api/userinfo"
},
"user": { ... },
"res": {
"allow": true
}
}