Given oauth_app resource not found - Magic.Link - react-native

I tries to integrate magic link social authentication to my React Native Mobile app and it always gives error Given oauth_app resource not found as in the attached file.
I use the code as described in the documentation and they're as follows,
const MagicElement = new Magic('pk_test_***********', {
extensions: [new OAuthExtension()],
});
try {
const result = await MagicElement.oauth.loginWithPopup({
provider: 'apple' /* 'google', 'facebook', 'apple', or 'github' */,
redirectURI: 'testapp://demo/your/oauth/callback',
});
console.log('result', result)
} catch (error) {
console.log('error', error)
}
}
https://docs.magic.link/client-sdk/web/social-login
Appreciate if anyone can help to solve this issue.

Be careful what parameters you are passing to loginWithPopup etc. An easy step to take if you encounter this screen is to look at the network tab filtered on "document" type.
In my case [object%20Object] in the request URL was a giveway:
https://auth.magic.link/v1/oauth2/[object%20Object]/start?magic_api_key=...
After fixing the parameters the URL became something like
https://auth.magic.link/v1/oauth2/google/start?magic_api_key=...
and the error went away.

Related

Strapi v4 Extending Server API for Plugins does not work

I am trying to follow the Strapi v4.0.0 guide on https://docs.strapi.io/developer-docs/latest/developer-resources/plugin-api-reference/server.html#entry-file for extending the users-permission plugin to add a custom route/controller, but so far have been unsuccessful. I add the custom files as stated in the docs, but there is no change in the UI.
I managed to get this to work for normal API highlighted in yellow, but was unable to do so for the users-permission plugin
In the previous version 3.6.8 this functionality was allowed through the extensions folder.
Am I missing something from the new guide, I even tried copying the files from node_modules > #strapi > plugin-users-permission and adding a new route and method to the exiting controller file but it still does not reflect the change in the section where we assign different route permission to roles. The user-permission plugin still shows the original routes, with no change.
Thanks,
I ran into this thread while researching pretty much the same issue, and I wanted to share my solution.
First of all, I found this portion of the documentation more useful than the one you referenced: https://docs.strapi.io/developer-docs/latest/development/plugins-extension.html
My goal was the write a new route to validate JWT tokens based on the comment made here: https://github.com/strapi/strapi/issues/3601#issuecomment-510810027 but updated for Strapi v4.
The solution turned out to be simple:
Create a new folder structure: ./src/extensions/user-permissions if it does not exist.
Create a new file ./src/extensions/user-permissions/strapi-server.js if it does not exist.
Add the following to the file:
module.exports = (plugin) => {
plugin.controllers.<controller>['<new method>'] = async (ctx) => {
// custom logic here
}
plugin.routes['content-api'].routes.push({
method: '<method>',
path: '/your/path',
handler: '<controller>.<new method>',
config: {
policies: [],
prefix: '',
},
});
return plugin;
};
If you're unsure what controllers are available, you can always check the API documentation or console.log(plugin) or console.log(plugin.controllers).
After the admin server restarts, you should see your new route under the user-permissions section as you would expect, and you can assign rights to it as you see fit.
My full strapi-server.js file including the logic to validate JWT:
module.exports = (plugin) => {
plugin.controllers.auth['tokenDecrypt'] = async (ctx) => {
// get token from the POST request
const {token} = ctx.request.body;
// check token requirement
if (!token) {
return ctx.badRequest('`token` param is missing')
}
try {
// decrypt the jwt
const obj = await strapi.plugin('users-permissions').service('jwt').verify(token);
// send the decrypted object
return obj;
} catch (err) {
// if the token is not a valid token it will throw and error
return ctx.badRequest(err.toString());
}
}
plugin.routes['content-api'].routes.push({
method: 'POST',
path: '/token/validation',
handler: 'auth.tokenDecrypt',
config: {
policies: [],
prefix: '',
},
});
return plugin;
};
When exporting routes you need to export the type, either content-api or admin. Look at the Strapi email plugin in node_modules for example, change the folder and file structure in your routes folder to match that and then you will be able to set permissions in the admin panel.
If your Strapi server is using Typescript, make sure that you name your extension files accordingly. So instead of strapi-server.js, you would need to name your file strapi-server.ts.

Testing Branch.IO referral links on react native

We use branch for referrals in our react native application. I have implemented branch successfully, now I want to test some scenarios.
When we click on a referral link, it navigates to app store or play store. But I want to do some debugging to identify if the params I pass are successfully send or not.
I have subscribed it like this. But how can I debug this with react-native debugger to see the console logs?
BranchIO.subscribe(async ({ error, params }) => {
if (error) {
console.log('Error from Branch: ', error);
return;
}
// Handle non-Branch URL.
if (params['+non_branch_link']) return;
// Indicates initialization success.
// No link was opened.
if (!params['+clicked_branch_link']) return;
const installParams = await BranchIO.getFirstReferringParams();
if (installParams?.$canonical_identifier === DeepLinkTypes.referral) {
store.dispatch(setReferralKey(installParams.referralKey));
}
// A Branch link was opened.
// Route link based on data in params
navigatePath(params.$deeplink_path);
});
To debug if you are able to fetch the associated link data or not you can put in a debugger at the following line-
const installParams = await BranchIO.getFirstReferringParams();
Also we would suggest you to kindly use/update the above line to use getLatestReferringParams
let lastParams = await branch.getLatestReferringParams()
instead of getFirstReferringParams() since there are some recent issues reported lately with this method.
You can print out the parameters in the console and see for the link data.

problem accessing elements using id/name for login form in cypress

I am trying to login to a form written in angular js but cypress throws the following exception:
Uncaught TypeError: $(...).materialScrollTop is not a function
This error originated from your application code, not from Cypress.
When Cypress detects uncaught errors originating from your application it will automatically fail the current test.
This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.
https://on.cypress.io/uncaught-exception-from-application
This is the cypress login code:
context('TestLogin', () => {
it('Test Login', () => {
cy.visit('url');
cy.get('input[id=Email]').type('email', {force: true});
cy.get('input[id=Password]').type('passcode', { force: true });
cy.get('button[type=submit]').click();
})
})
Since the login has a csrf token, I have used cy.request() as follows and I do get a response with status code 200 but when re-loading the site it goes back to login page.
describe("Tests for AntiForgeryToken", function () {
// variable from config, that contain Identity Server URL
const identityUrl = Cypress.config("identityServerUrl")
// command declaration that we are going to use in tests
// allows us to create request to server
Cypress.Commands.add("loginByToken", function (token, login, password) {
cy.request({
method: "POST",
failOnStatusCode: false,
url: `${identityUrl}/Account/Login`,
form: true,
body: {
email: login,
password: password,
__RequestVerificationToken: token,
RememberLogin: false
}
})
})
it("Should parse token from response body and return 200", function () {
cy.request(`${identityUrl}/Account/Login`)
.its("body")
.then((body) => {
const $html = Cypress.$(body)
// when the page is rendered
// we are trying to find the Request Token in the body of page
const token = $html.find("input[name=__RequestVerificationToken]").val()
// POST request with token and login data
// then we simply verify whether Indentity Server authorized us
cy.loginByToken(token, "test#test.com", "Test_1234")
.then((resp) => {
expect(resp.status).to.eq(200)
})
})
cy.visit(`${identityUrl}/Account/`);
})
Cypress documentation didn't provide much info about the exception.
Any insights from cypress experts are helpful.
As evident from the error, Cypress is failing the test as it found an exception in your application,this is not a cypress level exception but an uncaught exception in your app which is causing cypress to fail the test, this is pretty useful as you can check if its an actual error in your app and log it for the dev team to fix, check if you are able to reproduce this manually, either way i think the application code should be fixed to either fix the bug or catch the exception and return a valuable error message. If you want to disable this feature you can turn off all uncaught exception handling, so in your index.js or whatever file is the entry point add the following:
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
// you can also add a Debugger here to analyze the error
debugger;
return false;
});
not sure if turning this off will help as looks like there is something in your application which could be an issue, but this is just for informational purposes that you can turn this feature off if you needed to.
Here is the documentation for further reading : Cypress Events documentation
hope this helps

Upload images with apollo-upload-client in React Native

I'm trying out Prisma and React Native right now. Currently I'm trying to upload images to my db with the package _apollo-upload-client (https://github.com/jaydenseric/apollo-upload-client). But it's not going so well.
Currently I can select an image with the ImagePicker from Expo. And then I'm trying to do my mutation with the Apollo Client:
await this.props.mutate({
variables: {
name,
description,
price,
image,
},
});
But I get the following error:
Network error: JSON Parse error: Unexpected identifier "POST"
- node_modules/apollo-client/bundle.umd.js:76:32 in ApolloError
- node_modules/apollo-client/bundle.umd.js:797:43 in error
And I believe it's from these lines of code:
const image = new ReactNativeFile({
uri: imageUrl,
type: 'image/png',
name: 'i-am-a-name',
});
Which is almost identical from the their example, https://github.com/jaydenseric/apollo-upload-client#react-native.
imageUrl is from my state. And when I console.log image I get the following:
ReactNativeFile {
"name": "i-am-a-name",
"type": "image/png",
"uri": "file:///Users/martinnord/Library/Developer/CoreSimulator/Devices/4C297288-A876-4159-9CD7-41D75303D07F/data/Containers/Data/Application/8E899238-DE52-47BF-99E2-583717740E40/Library/Caches/ExponentExperienceData/%2540anonymous%252Fecommerce-app-e5eacce4-b22c-4ab9-9151-55cd82ba58bf/ImagePicker/771798A4-84F1-4130-AB37-9F382546AE47.png",
}
So something is popping out. But I can't get any further and I'm hoping I could get some tips from someone.
I also didn't include any code from the backend since I believe the problem lays on the frontend. But if anyone would like to take a look at the backend I can update the question, or you could take a look here: https://github.com/Martinnord/Ecommerce-server/tree/image_uploads.
Thanks a lot for reading! Cheers.
Update
After someone asked after the logic in the server I have decided to past it below:
Product.ts
// import shortid from 'shortid'
import { createWriteStream } from 'fs'
import { getUserId, Context } from '../../utils'
const storeUpload = async ({ stream, filename }): Promise<any> => {
// const path = `images/${shortid.generate()}`
const path = `images/test`
return new Promise((resolve, reject) =>
stream
.pipe(createWriteStream(path))
.on('finish', () => resolve({ path }))
.on('error', reject),
)
}
const processUpload = async upload => {
const { stream, filename, mimetype, encoding } = await upload
const { path } = await storeUpload({ stream, filename })
return path
}
export const product = {
async createProduct(parent, { name, description, price, image }, ctx: Context, info) {
// const userId = getUserId(ctx)
const userId = 1;
console.log(image);
const imageUrl = await processUpload(image);
console.log(imageUrl);
return ctx.db.mutation.createProduct(
{
data: {
name,
description,
price,
imageUrl,
seller: {
connect: { id: userId },
},
},
},
info
)
},
}
Solution has been found.
I am a little embarrassed that this was the problem that I faced and I don't know if I should even accept this answer because of awkward I felt when I fixed the issue. But....
There was nothing wrong with my code, but there was a problem with the dependencies versions. I tried to backtrack everything on my app, so I decided to start from the beginning and create a new account. I expected it to work just fine, but I got this error:
Error: Cannot use GraphQLNonNull "User!" from another module or realm.
Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.
https://yarnpkg.com/en/docs/selective-version-resolutions
Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.
Then I understand that something (that I didn't think of) was wrong. I checked my dependencies versions and compared them with Graphcool's example, https://github.com/graphcool/graphql-server-example/blob/master/package.json. And I noticed that my dependencies was outdated. So I upgraded them and everything worked! So that was what I had to do. Update my dependencies.
Moral of the story
Always, always check your damn dependencies versions...
Crawling through your code, I have found this repository, which must be the front-end code if I am not mistaken?
As you've mentioned, apollo-upload-server requires some additional set-up and same goes for the front-end part of your project. You can find more about it here.
As far as I know, the problematic part of your code must be the initialisation of the Apollo Client. From my observation, you've put everything Apollo requires inside of src/index folder, but haven't included Apollo Upload Client itself.
I have created a gist from one of my projects which initialises Apollo Upload Client alongside some other things, but I think you'll find yourself out.
https://gist.github.com/maticzav/86892448682f40e0bc9fc4d4a3acd93a
Hope this helps you! 🙂

Podio POST request returns unauthorized

I'm working on a Podio integration as a Slack bot.
I'm starting to use it just for use for my company to test it, then I could share it with everybody.
I've used the podio-js platform with Node JS, and started locally with a "web app" by starting from this example: https://github.com/podio/podio-js/tree/master/examples/password_auth
I need to do a post request, so I maintained all the code of the example in order to log in with user and password. The original code worked, then I changed the code to make a post request, in particular I change the lines of index.js into this:
router.get('/user', function(req, res) {
podio.isAuthenticated().then(function () {
var requestData = { "title": "sample_value" };
return podio.request('POST', '/item/app/15490175', requestData);
})
.then(function(responseData) {
res.render('user', { data: responseData });
})
.catch(function () {
res.send(401);
});
});
But in the end is giving a "Unauthorized" response.
It seems like the password auth doesn't let to make POST request to add new items! Is that possible?
I've already read all the documentation but I'm not able to explain why and how I can solve this.
Regards