How to use trello webhook callbackURL pointing to localhost in php codeigniter? - javascript

I have created a web-based system in codeigniter and some trello integration using its API services. I wanted to achieve something like if there is a new card created in a particular board it will also send a notification in my system that a new card is created. I started reading some documentation in trello webhooks but I just can't figure it out. Am I heading in the right way? Would it be valid if I provide a callbackURL pointing in localhost callbackURL: "localhost/main_controller/trelloCallback" ? However the code below returns a 400 status. Please help me. Thank you.
Javascript
$.post("https://api.trello.com/1/tokens/5db4c9fbb5b2kaf8420771072b203616f3874fa92a4c57f0c796cf90819fa05c/webhooks?key=a2a93deccc7064dek5f4011c2e9810d6", {
description: "My first webhook",
callbackURL: "localhost/dti_infosys/main_controller/trelloCallback",
idModel: "5a73c33ad9a2dk1b473612eb",
});
main_controller/trelloCallback
function trelloCallback() {
$json = file_get_contents('php://input');
$action = json_decode($json,true);
var_dump($action);
}

I know it's an old question, but this use case of having an external tool access our localhost for development is quite common.
So for anyone (OP included) that would like a cloud based service to be able to call a local endpoint, you can use tools like ngrok.
Basically, it sets up a URL accessible via internet that forwards all calls to one of your local ports.
Let's say that your local webserver running your PHP listens on the port 8000 on your machine.
With ngrok installed, you could execute the following command:
$> ngrok http 8000
That would set up the forwarding session:
ngrok by #inconshreveable
Session Status online
Session Expires 6 hours, 21 minutes
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://b5d44737.ngrok.io -> http://localhost:8000
Forwarding https://b5d44737.ngrok.io -> http://localhost:8000
You can then use any of the Forwarding addresses pointing to ngrok.io to access your local webserver through internet, meaning that if you were to provide an URL using any of these addresses instead of localhost to an external tool, it would be able to indirectly call your local endpoint.
In your case, your javascript call to create a Trello webhook would be:
$.post("https://api.trello.com/1/tokens/<YOUR_ACCESS_TOKEN>/webhooks?key=<YOUR_API_KEY>", {
description: "My first webhook",
callbackURL: "https://b5d44737.ngrok.io/dti_infosys/main_controller/trelloCallback",
idModel: "<YOUR_MODEL_ID>",
});
A bit of warning though: In the case of ngrok, the Forwarding URLs are randomized at each session startup, meaning that the webhooks you created on one session would not work an another session because there callbacksUrl wouldn't be valid anymore.
Note that you can subscribe to a paid plan to "reserve" ngrok subdomains and have URL consistency between sessions. Or you could manually update your webhooks callbackUrls with the new forarding URLs.
Anyway, I hope this will help!
P.S.: When the forwarding session runs, you can access localhost:4040 to inspect calls made on the forwarding URLs and retry some of them.

Related

Why my geoip query doesn't work in my production server?

I'm getting a hard time making Maxmind's geolite2 geolocation work on client side.
First I found this page: https://dev.maxmind.com/geoip/geolocate-an-ip/web-services?lang=en
And tried to use the urls in the curl command with authentication with my generated license key:
let geoData = axios.get('https:///geolite.info/geoip/v2.1/country/me?pretty', {
auth: {
username: <myuser>,
password: <mylicensekey>
}
});
this works in node but in client-side I get a CORS error.
then I found this other page: https://dev.maxmind.com/geoip/geolocate-an-ip/client-side-javascript?lang=en
It worked but I didn't want to use a non-npm packaged lib, so I inspected the lib's source-code and saw it call a different url from above:
https://geoip-js.com/geoip/v2.1/country/me?
trying this new url I saw it worked only WITHOUT authentication. I didn't understand why but anyway... it worked. Until I send the code to production at least.
With localhost it worked ok, but in production I get an error saying I have to register my domain.
The link provides in "register your domain" in this page: https://dev.maxmind.com/geoip/geolocate-an-ip/client-side-javascript?lang=en
leads to https://www.maxmind.com/en/accounts/790937/geoip/javascript/domains which asks me to enter the paid service registration page: https://www.maxmind.com/en/accounts/790937/geoip/javascript/domains
Is that it ? Client-side geolocation is only available as a paid service ?
So I want to know:
If there is a way to register domains for the free service, where do I register my domain?
If I can use https://geolite.info/geoip/v2.1/country/me?pretty url with id and license key in client-side, how to I get rid of the CORS message ?
I want to get the data without sending the user's IP, like when we access https://geolite.info/geoip/v2.1/country/me?pretty with id and license key.
Currently I want to use MaxMind's free data.

TikTok Login Kit web flow - keep getting Redirect URI error (code 10006)

I'm having an issue getting Login Kit to work. Similar to the question asked here I have the correct redirect domain listed in tiktok settings and the redirect_uri is basically just "domain/tiktok" but no matter what I do I get the same error message:
Below is my backend code - it's basically exactly the same as what is listed in the tiktok docs. Any help on this would be much appreciated!
const CLIENT_KEY = 'my_key'
const DOMAIN = 'dev.mydomain.com'
const csrfState = Math.random().toString(36).substring(2);
res.cookie('csrfState', csrfState, { maxAge: 60000 });
const redirect = encodeURIComponent(`https://${DOMAIN}/tiktok`)
let url = 'https://www.tiktok.com/auth/authorize/';
url += '?client_key=' + CLIENT_KEY;
url += '&scope=user.info.basic,video.list';
url += '&response_type=code';
url += '&redirect_uri=' + redirect;
url += '&state=' + csrfState;
res.redirect(url);
UPDATE 8/13/2022
I submitted the app for review and was approved so the status is now "Live in production" instead of "staging". The issue is still there - still showing error message no matter what domain / callback URL I use
UPDATE 8/16/2022
OK so I've made some progress on this.
First off - I was able to get the authentication/login screen to finally show up. I realized to do this you need to:
Make sure that the status of your app is "Live in production" and not "Staging". Even though when you create a new app you may see client_key and client_secret show up don't let that fool you - Login Kit WILL NOT WORK unless your app is submitted and approved
The redirect_uri you include in your server flow must match EXACTLY to whatever value you entered in "Registered domains" in the Settings page. So if you entered "dev.mydomain.com" in Settings then redirect_uri can only be "dev.mydomain.com" not "dev.mydomain.com/tiktok".
I think I might know what the issue is. My guess is that before - on the Settings page you had to enter the FULL redirect URL (not just the domain) and whatever redirect uri was included in the authorization query was checked against this value which was saved in TikTok's database (whatever was entered in the Settings page when path/protocol were allowed). At some point recently, the front-end business logic was changed such that you could only enter a domain (e.g., mydomain.com) on the Settings page without any protocols - however TikTok's backend logic was never updated so during the Login flow they are still checking against an EXACT match for whatever was saved in their DB as the redirect uri - this would explain why an app that was previously using the API with a redirect uri that DOES include protocols (e.g., for Later.com their redirect uri is https://app.later.com/users/auth/tiktok/callback) continues to work and why for any app attempting to save redirect WITH protocols are getting the error message screen. My gut feeling is telling me that the error is not on my part and this is actually a bug on TikTok's API - my guess is it can be addressed either by changing the front-end on the Settings page to allow for path/protocols (I think this is the ideal approach) or to change their backend so that any redirect uri is checked such that it must include 1 of the listed redirect domains.
I've been emailing with the TikTok team - their email is tiktokplatform#tiktok.com - and proposed the two solutions I mentioned above. I suggest if you're having the same issue you email them as well and maybe even link this StackOverflow question so that maybe it will get higher priority if enough people message them about it.
If you're looking for a shot-term hack I'd recommend creating a dedicated app on AWS or Heroku with a clean domain (e.g., https://mydomain-tiktok.herokuapp.com) and then redirect to either your dev or production environment by appending a prefix to the "state" query (e.g., "dev_[STATE_ID]"). I'll just reiterate I consider this a very "hacky" approach handling callbacks and would definitely not want to use something like this in production.
In my case, the integration worked after doing following steps:
In TikTok developers page:
Like #eugene-blinn said: make sure your app is in Live in production status (I couldn't find anything in the documentation about why Staging apps don't work);
Add the Login Kit product to your app and set the Redirect domain field with your host domain, for example: mywebsite.com.
In your code:
From my tests, I could add whanever url path I wanted, the only constraint was that the domain should match with step 2. So, yes, you can add https://mywebsite.com/whatever/path/you/want in redirect_url parameter.
That's it. It should work with these 3 steps.
Additionally, I got other issue related to use specific features in the scope property (like upload or read videos, etc), so here the solution as well:
Only add Video Kit product to the TikTok app and set video.upload or video.list in the scope authorize request won't work unless you also add the TikTok API product in your TikTok app as well. Btw, it neeeds to be approved too.
TikTok fixed the bug that resulted in URL mismatch with redirect domain from working. However, they fixed it only for paths (e.g., /auth/tiktok) but PORT additions still result in an error - so www.domain.com:8080/auth/tiktok won't work but www.domain.com/auth/tiktok WILL work
UPDATE 10/3/2022
Got the following response directly from TikTok engineering team:
At this point, we only support production integrations with TikTok for Developers and require that you have a URL without port number. However, we understand from your communication that this makes it harder for you to build, test, and iterate your integration with us. Unfortunately, at this time, we do not have a timeline for when this additional support for development servers will be added. We request that you only redirect to URLs without port numbers. Thank you for the feedback.
The frontend of the developer's dashboard still rejects protocol and path in validation. However, the backend skips the path validation.
To be able to update the "Redirect domain" simply:
Open dev tools in chrome and go to the "Network" tab.
Clic on "Save changes" button on the dashboard.
Right clic on the "publish" request that appeared and copy as cURL.
Modify the "redirect_domains" field in the request before pasting it in the terminal.
I believe the app still needs to be approved and in production to get it to work. I'm still waiting for approval and it has been a couple of weeks.
UPDATE 9/17/2022
Just like #mauricio-ribeiro, my app worked after it was approved to production. Setting up the redirect domain without path and scheme works just fine.
I had the same problem, my solution:
1.- In my TikTok App dashboard, the “redirect_uri” is: mydomain.com, without http/https and without path (/my-redirect-url). Also you can add subdomains using this rule
2.- In my code, I have to add http or https to the redirect_uri, and feel free to use path (/my-redirect-uri)
I hope this help you

NodeJS REST call with certificate. How could I know which file to use?

I'm trying to open a connexion to an IBM Cognos TM1 server through NodeJS/Axios and to do so I need to pass, during the first REST API Call everything which is needed to authenticate :
an username and password which I have
certificate information as SSL is set to true (I don't want to ignore self signed certificates)
I've found examples on how to pass certificate information with Axios but at this time I didn't succeed in getting it to work :-(
I've put in a dedicated folder, the whole ssl folder a TM1 client software is using:
E:\Development\nodejs\tm1query\assets\ssl\applixca.pem
E:\Development\nodejs\tm1query\assets\ssl\ibmtm1.arm
E:\Development\nodejs\tm1query\assets\ssl\ibmtm1.crl
E:\Development\nodejs\tm1query\assets\ssl\ibmtm1.kdb
E:\Development\nodejs\tm1query\assets\ssl\ibmtm1.rdb
E:\Development\nodejs\tm1query\assets\ssl\ibmtm1.sth
E:\Development\nodejs\tm1query\assets\ssl\importsslcert.exe
E:\Development\nodejs\tm1query\assets\ssl\tm1ca_v2.der
E:\Development\nodejs\tm1query\assets\ssl\tm1ca_v2.pem
E:\Development\nodejs\tm1query\assets\ssl\tm1store
E:\Development\nodejs\tm1query\assets\ssl\uninstallSSL.bat
E:\Development\nodejs\tm1query\assets\ssl\applixca.der
My problem is, which file do I need to use when creating the agent which will hold the connexion ?
Thanks in advance for helping or pointing me to information which can help me to go further in my understanding of how certificates works.
Regards,
Bob

facebook graph api node.js invalid appsecret_proof

this is my first post so please go easy on me!
I am a beginning developer working with javascript and node.js. I am trying to make a basic request from a node js file to facebook's graph API. I have signed up for their developer service using my facebook account, and I have installed the node package for FB found here (https://www.npmjs.com/package/fb). It looks official enough.
Everything seems to be working, except I am getting a response to my GET request with a message saying my appsecret_proof is invalid.
Here is the code I am using (be advised the sensitive info is just keyboard mashing).
let https = require("https");
var FB = require('fb');
FB.options({
version: 'v2.11',
appId: 484592542348233,
appSecret: '389fa3ha3fukzf83a3r8a3f3aa3a3'
});
FB.setAccessToken('f8af89a3f98a3f89a3f87af8afnafmdasfasedfaskjefzev8zv9z390fz39fznabacbkcbalanaa3fla398fa3lfa3flka3flina3fk3anflka3fnalifn3laifnka3fnaelfafi3eifafnaifla3nfia3nfa3ifla');
console.log(FB.options());
FB.api('/me',
'GET',
{
"fields": "id,name"
},
function (res) {
if(!res || res.error) {
console.log(!res ? 'error occurred' : res.error);
return;
}
console.log(res);
console.log(res.id);
console.log(res.name);
}
);
The error I am getting reads:
{ message: 'Invalid appsecret_proof provided in the API argument',
type: 'GraphMethodException',
code: 100,
fbtrace_id: 'H3pDC0OPZdK' }
I have reset my appSecret and accessToken on the developer page and tried them immediately after resetting them. I get the same error, so I don't think that stale credentials are the issue. My
console.log(FB.options())
returns an appropriate looking object that also contains a long hash for appSecretProof as expected. I have also tried this code with a number of version numbers in the options (v2.4, v2.5, v2.11, and without any version key). Facebook's documentation on this strikes me as somewhat unclear. I think I should be using v2.5 of the SDK (which the node package is meant to mimic) and making requests to v2.11 of the graph API, but ??? In any case, that wouldn't seem to explain the issue I'm having. I get a perfectly good response that says my appSecretProof is invalid when I don't specify any version number at all.
The node package for fb should be generating this appSecretProof for me, and it looks like it is doing that. My other info and syntax all seem correct according to the package documentation. What am I missing here? Thank you all so much in advance.
looks like you have required the appsecret_proof for 2 factor authorization in the advance setting in your app.
Access tokens are portable. It's possible to take an access token generated on a client by Facebook's SDK, send it to a server and then make calls from that server on behalf of the client. An access token can also be stolen by malicious software on a person's computer or a man in the middle attack. Then that access token can be used from an entirely different system that's not the client and not your server, generating spam or stealing data.
You can prevent this by adding the appsecret_proof parameter to every API call from a server and enabling the setting to require proof on all calls. This prevents bad guys from making API calls with your access tokens from their servers. If you're using the official PHP SDK, the appsecret_proof parameter is automatically added.
Please refer the below url to generate the valid appsecret_proof,and add it to each api call
https://developers.facebook.com/docs/graph-api/securing-requests
I had to deal with the same issue while working with passport-facebook-token,
I finally released that the problem had nothing to have with the logic of my codebase or the app configuration.
I had this error just because I was adding intentionally an authorization Header to the request. so if you are using postman or some other http client just make sure that the request does not contain any authorization Header.

How to set up a Google Drive Client ID for access without a local server?

I'm wondering if it's possible to, say, open up a jsfiddle on a random computer and log in and authenticate and use the drive API, without having to have a local server running all the time? And how exactly does one go about setting this up? I'm sorry if this is a simple question but I'm just sorta lost because the instructions that I've found so far are unclear.
Edit:
So far I have, following from here and here:
Created a project via the Google Developers Console.
Opened up that project there, navigated to APIs under APIs & auth, and ensured that Drive API was enabled
Went into credentials, and clicked on "Create a new Client ID"
Selected "Web Application"
Set authorized javascript origins to http://localhost:4567
Deleted any contents in Redirect URI's and left it blank, then pressed "Create Client ID."
Took a sample like this, this, or this, and stored it in a local file named named index.html.
This wouldn't run by simply opening in a brower, so I had to host a local server
I navigated into that directory in the command line and then typed "python -m SimpleHTTPServer 4567" (without the quotes) and this hosted a local server
Opened http://localhost:4567 in my web brower, and all of these samples work fine, after copying the newly created client ID into these files where they ask for it.
I also have made a python application, to use pydrive I:
Clicked on "Create a new Client ID", then "Installed Application" and "Other", then "Create Client ID."
Next I went to the Old Google APIs Console, clicked on API Access, found that client ID, and clicked Download JSON.
I placed this client_secrets.json next to my python application, and this allowed pydrive to authenticate successfully and I could access and modify my google drive files anywhere using that client ID. Though of course I deleted this client_secrets.json before giving the application to another person, and showed them how to do this process as well.
However, beyond this, I'm a little unsure about, specifically:
How one can use the drive api in web applications without having to set up a local server, say simply by running code in jsfiddle and having requests sent through my project via using a Client ID, and
If a local server is set up that can be accessed by anyone on the web, how one can modify the above steps to allow any client to open that server's webpage to use the google drive API?
I know that I most likely need to set up a Public API access in the developers console, but am not entirely sure what Referers I should use as well. So is there a simple way to do any of this?
I also know that gspread can open google excell spreadsheets only using the client's username and password, so I'm suspecting that what I'm looking for is possible, but I'm not sure.
Okay, so I found a solution that works pretty well:
Make an OAuth.io account (It's free).
Once you're logged in, go to your oauth.io dashboard.
You should be looking at a Default App, or you can make another one it doesn't really matter.
Under "Domains & URLs whitelist", you'll see a little box that says "localhost." Type in "
http://fiddle.jshell.net/" (without the quotes) and press enter. This allows any jsfiddle to authenticate with your application
Next, we need to enable Google Drive support
Go to the Google Developers Console
Like before, navigate to Credentials under APIs and Auth.
Click "Create new Client ID"
Select Web Application
Under "Redirect URIs" put "https://oauth.io/auth" and "http://oauth.io/auth" (without quotes, on separate lines)
Under "Javascript Origins" put "https://oauth.io" and "http://oauth.io"
Press "Create Client ID"
Now go to your Oauth.io key manager. Click on Google Drive in the list to the left. Press next, and enter your client_id and client_secret that you created in the previous step (via the Google Developers Console)
Select online (at least online is preferred since offline should be for server side only)
Click on the Scope text book, and select "https://www.googleapis.com/auth/drive (View and manage the files in your google Drive)."
Press finish. Now click on the Try Auth button, and hopefully you should get some output like
{
"access_token": "ya29.AwH-1N_gnstLBuZfOR4W9CCcggKrQpMyKYV4QVEtCiIzHozNU5AfUJoYQzukALfjdiw2iOCUve7JbQ",
"token_type": "Bearer",
"expires_in": 3600,
"provider": "google_drive"
}
To use this, you can do something like:
// This only works because we're set to "No wrap - in <head>"
function ShowDriveFileList() {
var accessToken;
// Initialize OAuth with our key
OAuth.initialize('lmGlb8BaftfF4Y5en_c8XYOSq2A');
// Connect to google drive, and print out file list
OAuth.popup('google_drive').done(function (result) {
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "https://www.googleapis.com/drive/v2/files", false);
xmlHttp.setRequestHeader("Authorization", "Bearer " + result.access_token);
xmlHttp.send(null);
alert(xmlHttp.responseText);
}).fail(function (err) {
alert(err);
});;
}
Which you can find at http://jsfiddle.net/JMTVz/41/. This uses my oauth.io client id, but you can replace it with yours and it should work as well.
You can do the same thing using the OAuth Playground.
See How do I authorise an app (web or installed) without user intervention? (canonical ?)
Step 11 will be different. Instead of pasting the refresh token into your server app (which you don't have), you'll paste the access token into your JS in the same way as you are doing in your answer.

Categories