How can I send a POST request to start a password reset flow using axios - post

I'm implementing the Forgot password feature using truevault API. Now, I've been testing the requests following the flow with Postman, and it works, but, when I started coding using axios, it keeps throwing issues about authentication. I've tried several combinations (logical ones, not just random craziness).
Also, worth mentioning that I was able to list my truevault users from UI (not only postman), and tried to mimic the same principle to the post request, but it didn't work
Here is the postman request that worked for me:
for the url request, method is: POST
url: https://api.truevault.com/v1/password_reset_flows
For the Authorization tab, I filled the "username" field with the truevault user API Key, and left the "password" field empty
And the "Body" tab, I filled it with a Json text, and for radio button options, I selected raw, and picked json as the format. (these are the only tabs being used)
The json body is as follow
{
"name":"XXXXX password reset",
"sg_template_id":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXcf42",
"sg_api_key":"XX.XXXXXXXXXXXXXXXXXXXXXX.XXXXXX_XXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXZftJo",
"user_email_value_spec":{
"system_field":"username"
},
"from_email_value_spec":{
"literal_value":"do-not-reply#XXXXXX.com"
},
"substitutions":{
"{{FIRST_NAME}}":{
"user_attribute":"first_name"
}
}
}
And the result was successful,
Now, when I tried with axios, I kept getting the auth error. Code is as follows:
createPasswordResetFlow()
{
axios.defaults.headers.common["Authorization"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX27"; //tv user API KEY
axios.defaults.headers.post["Content-Type"] = "application/json";
var request = axios.post("https://api.truevault.com/v1/password_reset_flows",
{
auth:
{
username: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX27',
password: ""
},
data:
{
"name": "XXXXX password reset",
"sg_template_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXcf42",
"sg_api_key": "XX.XXXXXXXXXXXXXXXXXXXXXX.XXXXXX_XXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXZftJo",
"user_email_value_spec":
{
"system_field": "username"
},
"from_email_value_spec":
{
"literal_value": "do-not-reply#XXXXXX.com"
},
"substitutions":
{
"{{FIRST_NAME}}":
{
"user_attribute": "first_name"
}
}
}
})
.then((res) =>
{
console.log(res);
return res.data.users;
})
.catch(error =>
{
console.log('error', error);
return error;
});
}
As mentioned also earlier, I've been researching and trying, but to no avail, if someone could help me please.

There are two issues with the JS code you shared which are causing the problem:
The line where you set the default Auth header looks like this: axios.defaults.headers.common["Authorization"] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX27"; //tv user API KEY. Note that the Authorization header is being set to the API key, not an HTTP Basic Auth header value. If you want to set the default auth header this way, you need to set it to base64(API_KEY:) rather than just API_KEY.
According to the axios docs the post method has the signature .post(url, data, config). As a result, your code is POSTing a JSON object that looks like {auth: ..., data: ...}.
Try removing the line where you set the authorization header, and changing the post call to look something like this:
axios.post("https://api.truevault.com/v1/password_reset_flows",
{
"name": "XXXXX password reset",
"sg_template_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXcf42",
"sg_api_key": "XX.XXXXXXXXXXXXXXXXXXXXXX.XXXXXX_XXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXZftJo",
"user_email_value_spec":
{
"system_field": "username"
},
"from_email_value_spec":
{
"literal_value": "do-not-reply#XXXXXX.com"
},
"substitutions":
{
"{{FIRST_NAME}}":
{
"user_attribute": "first_name"
}
}
}
}, {
username: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX27',
password: ""
})

Related

Display only endpoints available to user in Swagger after his login

I would like to setup the follownig workflow:
Initially, without login, Swagger shows only 2-3 endpoints - this will be done by providing limited openapi3 json from backend, no problem;
User logs in via Authorize button (works, openapi3 json has necessary info);
After login, Swagger emits one more request with user credentials, backend provides new openapi3 json with endpoints available to this specific user and Swagger redraws the page with new data. Preferably, user is still logged in.
Is it possible to do Item 3 with Swagger? How can I manually emit request from Swagger with OAuth2 bearer token (since user logged, token must present somwhere) and redraw Swagger page?
The task was done via Swagger customization using its plugin system.
Actually Swagger is a JavaScript (Babel, Webpack) project using React / Redux and it was a little bit hard to dig into it since I do not know React (my tool is Python) but finally I managed.
Here is the code for my custom plugin with comments:
const AuthorizedPlugin = function(system) {
return {
statePlugins: {
auth: { // namespace for authentication subsystem
// last components invoked after authorization or logout are
// so-called reducers, exactly they are responsible for page redraw
reducers: {
"authorize_oauth2": function(state, action) {
let { auth, token } = action.payload
let parsedAuth
auth.token = Object.assign({}, token)
parsedAuth = system.Im.fromJS(auth)
var req = {
credentials: 'same-origin',
headers: {
accept: "application/json",
Authorization: "Bearer " + auth.token.access_token
},
method: 'GET',
url: system.specSelectors.url()
}
// this is the additional request with token I mentioned in the question
system.fn.fetch(req).then(
function (result) {
// ... and we just call updateSpec with new openapi json
system.specActions.updateSpec(result.text)
}
)
// This line is from the original Swagger-ui code
return state.setIn( [ "authorized", parsedAuth.get("name") ], parsedAuth )
},
"logout": function(state, action) {
var req = {
credentials: 'same-origin',
headers: { accept: "application/json" },
method: 'GET',
url: system.specSelectors.url()
}
// for logout, request does not contain authorization token
system.fn.fetch(req).then(
function (result) {
system.specActions.updateSpec(result.text)
}
)
// these lines are to make lock symbols gray and remove credentials
var result = state.get("authorized").withMutations(function (authorized) {
action.payload.forEach(function (auth) {
authorized.delete(auth);
});
});
return state.set("authorized", result)
}
}
}
}
}
}
Insert this plugin as usual:
const ui = SwaggerUIBundle({{
url: '{openapi_url}',
dom_id: '#swagger-ui',
defaultModelsExpandDepth: -1,
displayOperationId: false,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
plugins: [
AuthorizedPlugin
],
layout: "BaseLayout",
deepLinking: true
})

Store Rails Json response in ember

I am working on authentication of a user .
currently i am posting a session with username and password . which will be sent to rails bcrypt for authentication ,if authentication is true then this will return a json of user object .
how will i grab this user in ember so that i can store it in my service .
Login Function :
login(user) {
console.log("this is working ")
//this.get('sessionaccount').login(user)
this.store.createRecord('session', {
email: this.currentModel.email,
password: this.currentModel.password
}).save().then(function(data) {
console.log(data.id)
this.id = data.id
this.get('sessionaccount').login(data)
});
}
Ember Data is meant to be used together with resources. It doesn't work well with other types of data. I assume you will only have one session client-side, so I would not recommend to model that one with Ember Data but using plain fetch instead:
async login() {
let response;
try {
response = await fetch('/login', {
method: 'POST',
headers: {
Content-Type: 'application/json'
},
body: JSON.stringify({
email: this.currentModel.email,
password: this.currentModel.password
})
});
} catch (error) {
// handle connectivity issues
}
if (!response.ok) {
// handle server-side errors
// this may include wrong credentials
}
// parse the returned data as json
let data = await resonse.json();
// do something with the returned data
}
I'm using async / await instead of a chaning .then() cause it's much easier to read in my opinion.
If the data returned by the server is a resource representing data that should be handled with Ember Data, you could (and should) load it into the store, using pushPayload() method of Ember Data's StoreService.

Unsupported grant type error in RingCentral

I am calling the API to refresh my access token on RingCentral but it throws the following error
{
"error":"invalid_request",
"error_description":"Unsupported grant type",
"errors":[
{
"errorCode":"OAU-250",
"message":"Unsupported grant type"
}
]
}
Can anyone help me out?
Check and see if you are posting the grant_type form field and that it's set to refresh_token
I am using the RingCentral API available from RingCentral GitHub
Here is an example of an authentication request:
var request = new Request("/restapi/oauth/token",
new Dictionary<string, string> {
{ "grant_type", "authorization_code" },
{ "redirect_uri", redirectUri },
{ "code", authCode },
{ "refresh_token_ttl", "604800" } });
grant_type=refresh_token is supported by all the platform_type except server/bot platform type. Make sure you haven't created your apps with that platform type.
The parameter for refresh_token is almost same as grant_type password with minor change.
url will be same: https://platform.devtest.ringcentral.com/restapi/oauth/token
Headers:
"Accept":"application/json“
"Content-Type":"application/x-www-form-urlencoded“
"Authorization",:"Basic <ClientID:ClientSecret in base 64>
Body:
In body, we need to pass the parameters in following way :
username=<account phone number>&password=<account password>&extension=<your extension>&grant_type=refresh_token&refresh_token=<the refresh token generated>

full email validation on Meteor using Mandrill

I have read several SO posts about using Mandrill with Meteor.js for email validation, yet I've found a problem no others seem to face.
Ultimately, I want the verified property of a user to be set to true after clicking the email validation url. I am using Mandrill to send customized email templates containing a verification_url. I have the accounts-password and accounts-ui packages added. My code looks like this:
if (Meteor.isServer) {
Meteor.startup(function () {
Mandrill.config({
username: process.env.MANDRILL_API_USER,
key: process.env.MANDRILL_API_KEY
// port: 587, // defaults to 465 for SMTP over TLS
// host: 'smtp.mandrillapp.com', // the SMTP host
// baseUrl: 'https://mandrillapp.com/api/1.0/' // update this in case Mandrill changes its API endpoint URL or version
});
Accounts.config({
sendVerificationEmail: true
});
Accounts.emailTemplates.verifyEmail.html = function (user, url) {
var referralCode = Random.id();
var result;
try {
result = Mandrill.templates.render({
template_name: 'email-verification',
template_content: [],
merge_vars: [
{
name: 'SUBJECT',
content: 'my fancy subject'
},
{ name: 'EMAIL',
content: 'my fancy email'
},
{
name: 'VERIFICATION_URL',
content: 'http://localhost:3000/?ref=' + referralCode
}
]
});
} catch (error) {
console.error('Error while rendering Mandrill template', error);
}
return result.data.html;
};
});
When I create a user the verification email is correctly sent, however when I click the verification link within the email, nothing is done on the server, i.e. I look at my app's MongoDB and see on the user document still have the property verified: false. I've tried to work with onEmailVerificationLink (http://docs.meteor.com/#/full/Accounts-onEmailVerificationLink) but I get an error in the console saying onEmailVerificationLink has already been called, which happens because accounts-ui is apparently calling it for me. How do I do proper email verification in Meteor.js using Mandrill?
Finally figured it out. Instead of the line
content: 'http://localhost:3000/?ref=' + referralCode
I should replace it with
content: url
since Meteor is already creating the validation url for me, and passing it in through the "url" argument of the function. Clearly I didn't need referralCode either

Rikulo security client side login

I've been trying to create a Dart SPA using Rikulo security to log in. I have been unable to do so successfully. I found the following in the docs:
//If you'd like to login in an Ajax request, SOAP or others,
//you can invoke this method directly by providing the username, password
//and, optional, rememberMe:
//prepare username, password, rememberMe from, say, Ajax
security.login(connect, username: username, password: password,
rememberMe: rememberMe, redirect: false);
My question is how do I return a success/fail login value from Rikulo security for use on the client side.
An example would be extremely helpful. Thanks in advance.
I assume you'd like to log in over Ajax (and JSON). Basically, it is no different from handling Ajax -- you can refer to the Handle Post requests section here.
import "dart:convert";
import "package:rikulo_commons/convert.dart";
Future login(HttpConnect connect) {
return readAsJson(connect.request).then((Map<String, String> data) {
return security.login(connect, redirect: false,
username: data["username"],
password: data["password"]);
})
.then((_) {
//login successfully
response
..headers.contentType = contentTypes["json"]
..write(JSON.encode({"result": "success"}));
})
.catchError((ex) {
if (ex is AuthenticationException) {
// login fail
response
..headers.contentType = contentTypes["json"]
..write(JSON.encode({'result': 'fail'}));
} else {
throw new Http404.fromConnect(connect);
}
});
}

Resources