Fetch with encrypted password - javascript

I'm trying to authenticate to an API via fetch. For that, I'm using an encrypted username and password. The problem is that no matter what I do, the response I get from the API is that my password is invalid. I know the password works because it was provided by my admins.
This is the code I'm using:
import CryptoJS from 'crypto-js';
import CryptoJSAesJson from './helpers/helpers';
var username = 'myusername';
var pass = 'mypassword';
var hash = CryptoJS.SHA1(username).toString();
var password = CryptoJS.AES.encrypt(JSON.stringify(pass), 'mypassphrase', {format: CryptoJSAesJson}).toString();
var credentials = {
user: hash,
password: password
}
fetch("https://demo.mediainfo.com/api/user/login", {
body: JSON.stringify(credentials),
headers: {
"Content-Type": "application/json"
},
method: "POST"
}).then(response => {
// do something with the response
});
On helpers.js I have this code:
var CryptoJSAesJson = {
stringify: function (cipherParams) {
var j = {ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64)};
if (cipherParams.iv) j.iv = cipherParams.iv.toString();
if (cipherParams.salt) j.s = cipherParams.salt.toString();
return JSON.stringify(j).replace(/\s/g, '');
},
parse: function (jsonStr) {
var j = JSON.parse(jsonStr);
var cipherParams = CryptoJS.lib.CipherParams.create({ciphertext: CryptoJS.enc.Base64.parse(j.ct)});
if (j.iv) cipherParams.iv = CryptoJS.enc.Hex.parse(j.iv);
if (j.s) cipherParams.salt = CryptoJS.enc.Hex.parse(j.s);
return cipherParams;
}
}
export default CryptoJSAesJson;
Unfortunately the API documentation is null so I'm not sure what could be the problem, the only message I get when fetching is: "Wrong password exchange. Please contact administrator."
Thanks!

Related

error: "unsupported_grant_type" using reddit API, javascript

During the Oauth process for reddit API, I have gotten stuck at the access token request, getting an error saying 'unsupported_grant_type'. The API documentation says to use grant type 'authorization_code' which is what I have set now. I've tried using a string, URLSearchParams, and formData to correct it thinking that it was the format that was breaking it but nothing has worked.
Here is the function in question:
async function fetchAccessToken(){
console.log("fetching access token...");
const cred = btoa(`${client_id}:${client_secret}`);
var form = new FormData()
form.append('code', authCode)
form.append('grant_type', grantType)
form.append('redirect_uri', redirect_uri)
const response = await fetch('https://ssl.reddit.com/api/v1/access_token', {
method: 'POST',
headers: {
'Content-Type':"application/x-www-form-urlencoded",
'Authorization':`Basic ${cred}`
},
body: form
})
const data = await response.json();
console.log(response.status);//says 200
console.log(data);//says {error: 'unsupported_grant_type'}
}
I've been stuck here for over a week, any help would be appreciated.
I was stuck on a similar issue - ended up using Axios.
Make sure to add a unique 'User-Agent'.
const axios = require("axios").default;
const url = require("url");
async function fetchAccessToken(){
console.log("fetching access token...");
const client_id = "";
const client_secret = "";
const username = "":
const password = "";
const authData = {
grant_type: "password",
username: username,
password: password,
};
const params = new url.URLSearchParams(authData);
const response = await axios({
url: 'https://www.reddit.com/api/v1/access_token',
method: 'POST',
headers: {
'User-Agent': "myApp:V0.1 by Dschaar", //some unique user agent
},
auth: {
username: username,
password: password,
}
params: params
})
console.log(response.data);
}

is there anyway i can refresh spotify token in react?

I create a function that I can log in to my Spotify and get the access token and I create a function to refresh my token but it does not work properly when I pass it to the request function with Axios and it returns 400 or 404.
what should I do ?
here is my code :
const AUTH_URL =
" https://accounts.spotify.com/authorize?client_id=MY_ID&response_type=token&redirect_uri=http://localhost:3000/&scope=user-read-playback-state";
let Login = () => {
const spotifyHandle = (params) => {
const afterHashtag = params.substring(1);
const param = afterHashtag.split("&");
const paramsSplit = param.reduce((Para, currentPara) => {
const [key, value] = currentPara.split("=");
Para[key] = value;
return Para;
}, {});
return paramsSplit;
};
useEffect(() => {
if (window.location.hash) {
const { access_token, expires_in } = spotifyHandle(window.location.hash);
localStorage.clear();
localStorage.setItem("accessToken", access_token);
localStorage.setItem("expiresIn", expires_in);
}
});
return (
<div>
<a href={AUTH_URL}>
<button>Login</button>
</a>
</div>
);
};
here the refresh function:
let refresh = async () => {
const clientId = "id";
const clientSecret = "secret";
const headers = {
headers: {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
},
auth: {
username: clientId,
password: clientSecret,
},
};
const data = {
grant_type: "client_credentials",
};
try {
const response = await axios.post(
"https://accounts.spotify.com/api/token",
qs.stringify(data),
headers
);
console.log(response.data.access_token);
return response.data.access_token;
} catch (error) {
console.log(error);
}
};
The Spotify API follows the OAuth 2.0 specs and it requires (as presented at this Spotify's documentation section):
grant_type to be equal to authorization_code
code to be equal to the authorization code returned from the initial request to the Account /authorize endpoint
redirect_uri This parameter is used for validation only (there is no actual redirection). The value of this parameter must exactly match the value of redirect_uri supplied when requesting the authorization code.
And a Authorization is also required at the request header, as stated at the docs:
Base 64 encoded string that contains the client ID and client secret key. The field must have the format: Authorization: Basic *<base64 encoded client_id:client_secret>*

Session cookie from node-fetch is invalid?

I am writing a javascript program (for a github action) right now but ran into a problem.
I was trying to log into www.overleaf.com and access the page https://www.overleaf.com/project after generating a session cookie by sending a POST request to https://www.overleaf.com/login with my credentials and the csrf token.
The response contained the requested token in the set-cookie header as expected, however, when I tried to access https://www.overleaf.com/project via GET, I get redirected back to https://www.overleaf.com/login
When copying a session cookie saved in my browser, the request works just fine as expected.
I tried doing the same thing in the command line with cURL and it worked there.
I am fairly certain my authentication request is accepted by Overleaf's server, because I have tried intentionally incorrectly sending the password or the csrf token and in both cases, the response does not give me a new session cookie but sends the old one.
If anyone has any clue what is going wrong, I'd be very thankful for your input.
This is what worked in the terminal, which I'm trying to replicate in javascript with node-fetch:
curl -v --header "Content-Type: application/json" --cookie "GCLB=someothercookie;overleaf_session2=firstsessioncookie" --data '{"_csrf":"the_csrf_token", "email": "MYEMAIL", "password":"MYPASSWORD"}' https://www.overleaf.com/login
to get the cookie and csrf token and
curl -v https://www.overleaf.com/project --cookie "overleaf_session2=returnedsessioncookie; GCLB=someothercookie" as the request that returns the html page of my projects.
This is my javascript code, I have double, triple, quadruple checked it but I think I'm missing something.
const fetch = require("node-fetch");
const parser = require("node-html-parser");
const scparser = require("set-cookie-parser");
async function run() {
const email = process.env.EMAIL;
const password = process.env.PASSWORD;
var cookies = await login(email, password);
console.log(await all_projects(cookies));
}
async function login(email, password) {
const login_get = await fetch("https://www.overleaf.com/login");
const get_cookies = login_get.headers.raw()["set-cookie"];
const parsed_get_cookies = scparser.parse(get_cookies, {
decodeValues: false
});
const overleaf_session2_get = parsed_get_cookies.find(
(element) => element.name == "overleaf_session2"
).value;
const gclb = parsed_get_cookies.find(
(element) => element.name == "GCLB"
).value;
console.log("overleaf_session2_get:", overleaf_session2_get, "gclb:", gclb);
const get_responsetext = await login_get.text();
const _csrf = parser
.parse(get_responsetext)
.querySelector("input[name=_csrf]")
.getAttribute("value");
login_json = { _csrf: _csrf, email: email, password: password };
console.log(login_json);
const login_post = await fetch("https://www.overleaf.com/login", {
method: "post",
body: JSON.stringify(login_json),
headers: {
"Content-Type": "application/json",
"Cookie": "GCLB=" + gclb + ";overleaf_session2=" + overleaf_session2_get
}
});
const post_cookies = login_post.headers.raw()["set-cookie"];
const parsed_post_cookies = scparser.parse(post_cookies, {
decodeValues: false
});
const overleaf_session2_post = parsed_post_cookies.find(
(element) => element.name == "overleaf_session2"
).value;
console.log(
"successful:",
overleaf_session2_get != overleaf_session2_post ? "true" : "false"
);
console.log(await fetch("https://www.overleaf.com/project", {
headers: {
"Cookie": "overleaf_session2=" + overleaf_session2_post
}
}))
return "overleaf_session2=" + overleaf_session2_post;
}
async function all_projects(cookies) {
const res = await fetch("https://www.overleaf.com/project", {
headers: {
Cookie: cookies
}
});
return res;
}
run();
Yes your authentication request is probably valid however this is likely to be a security issue which browsers do not allow you to do such thing and freely access another website's cookie.
Browsers do not allow you to access other domain's cookies, If they did then web would be an unsafe place because for example Stackoverflow could access my Facebook account cookie and extract my personal information.
I fixed my issue by not using node-fetch and switching to https.
Here is what worked:
async function login(email, password) {
//GET login page
const get = await get_login();
//get necessary info from response
const csrf = parser
.parse(get.html)
.querySelector(`meta[name="ol-csrfToken"]`)
.getAttribute("content");
const session1 = scparser
.parse(get.headers["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "overleaf_session2").value;
const gclb = scparser
.parse(get.headers["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "GCLB").value;
//POST login data
const post = await post_login(csrf, email, password, session1, gclb);
//get necessary data from response
const session2 = scparser
.parse(post["set-cookie"], { decodeValues: false })
.find((cookie) => cookie.name == "overleaf_session2").value;
//GET new csrf token from project page
const projects = await get_projects(session2, gclb);
const csrf2 = parser
.parse(projects.html)
.querySelector(`meta[name="ol-csrfToken"]`)
.getAttribute("content");
//return data
return {
session: session2,
gclb: gclb,
csrf: csrf2,
projects: projects.html
};
}
async function get_login() {
const url = "https://www.overleaf.com/login";
return new Promise((resolve) => {
https.get(url, (res) => {
var data;
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve({ html: data, headers: res.headers });
});
});
});
}
async function get_projects(session2, gclb) {
const url = "https://www.overleaf.com/project";
return new Promise((resolve) => {
https.get(
url,
{ headers: { Cookie: `GCLB=${gclb};overleaf_session2=${session2}` } },
(res) => {
var data;
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve({ html: data, headers: res.headers });
});
}
);
});
}
async function post_login(_csrf, email, password, session1, gclb) {
const url = "https://www.overleaf.com/login";
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
Cookie: `GCLB=${gclb};overleaf_session2=${session1}`
}
};
const postData = {
_csrf: _csrf,
email: email,
password: password
};
return new Promise((resolve) => {
var req = https.request(url, options, (res) => {
resolve(res.headers);
});
req.on("error", (e) => {
console.error(e);
});
req.write(JSON.stringify(postData));
req.end();
});
}

Netlify lambda function is working but getting undefined response and status 500

I have a pretty straight forward post request using axios.
I have played around with JSON.stringfy, adjusted my try/catch statement, and played around with various headers. No luck.
After doing some reading I think it has to do with the fact that I am not (req, res) anywhere. Thus, the lamda function returns undefined but the post request still works.
Just looking for a direction to go in because I am lost with how to implement (req,res).
const axios = require("axios");
// Declare spreadsheet and values to append
const spreadsheetId = "SECRET";
// build data for a POST request
const baseUrl = "https://pushtogsheet.herokuapp.com";
const query = `SECRET`;
const url = new URL(
`/proxy/google-sheets/${spreadsheetId}/values/A1:append?${query}`,
baseUrl
);
module.exports.handler = async (event, context) => {
try {
const dataHanlder = event.body;
const data = await JSON.parse(dataHanlder);
const {
firstName,
lastName,
email,
company,
empRange,
phone,
leadCountry,
signupType,
timezone,
utmSource,
utmMedium,
utmCampaign,
utmTerm,
utmContent,
} = data;
const excelArray = [
[
firstName,
lastName,
email,
company,
phone,
empRange,
timezone,
leadCountry,
signupType,
utmSource,
utmMedium,
utmCampaign,
utmTerm,
utmContent,
],
];
const excelString = await JSON.stringify({ values: excelArray });
const config = {
headers: {
"Pizzly-Auth-Id": "SECRET",
// "Content-Type": "text/plain",
},
};
const res = axios.post(url.href, excelString, config);
console.log("POST request status code", res.status);
} catch (error) {
console.log(error);
}
};

Fetch method Formpara Javascript

this is my jersey server, REST api using java
#POST
#Produces({MediaType.APPLICATION_JSON})
#Path("registration")
public User register(#FormParam("username") String userName, #FormParam("password") String password) {
boolean isOk = true;
User newUser =null;
List<User> userList = em.createNamedQuery("User.findAll").getResultList();
for(User user: userList){
if(user.getUsername().equals(userName)){
isOk = false;
}
}
if(isOk == true){
newUser = new User();
newUser.setUsername(userName);
newUser.setPassword(password);
super.create(newUser);
}
return newUser;
}
I use javascript to POST new user to the server via formdata
buttonLogin.addEventListener('click', (evt) => {
evt.preventDefault();
console.log('login');
const imgData = new FormData();
imgData.append('username', 'newuser');
imgData.append('password', '123');
for (var p of imgData) {
console.log(p);
}
//
let url = endPointUrl + `webresources/users/registration`;
const myHeader = new Headers({'Content-Type':"application/x-www-form-urlencoded"});
fetch(url, {
method: 'POST',
headers: myHeader,
data: imgData
})
.then(json)
.then((data) => {
console.log(data);
});
});
My server did receive formparam but it is null object. I expect that the server will receive username: "newuser" and password "123" but server receive null object
I test server with postman and everything is ok. So I assume that the problem is javascript code.
Could you show me what is wrong with my code. Thank

Categories

Resources