coverting javascript to python - javascript

I have a yale smart alarm and come across the the below javascript that allows you to access the alarm to get the status and set it. I'm wanting to use this in my home assistant set to which uses python.
const fetch = require('node-fetch');
const setCookie = require('set-cookie-parser');
const urls = {
login: 'https://www.yalehomesystem.co.uk/homeportal/api/login/check_login',
getStatus: 'https://www.yalehomesystem.co.uk/homeportal/api/panel/get_panel_mode',
setStatus: 'https://www.yalehomesystem.co.uk/homeportal/api/panel/set_panel_mode?area=1&mode=',
};
function getSessionCookie(username, password) {
let sessionCookie = null;
return fetch(urls.login, {
method: 'POST',
body: `id=${encodeURIComponent(username)}&password=${password}&rememberme=on&notify_id=&reg_id=Name`,
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'
},
})
.then((res) => {
sessionCookie = res.headers._headers['set-cookie'];
return res.json();
}).then(json => {
if (json.result === '0') {
return Promise.reject('Incorrect account details');
}
else {
return sessionCookie[0];
}
})
}
function getStatus(sessionCookie) {
return fetch(urls.getStatus, {
method: 'POST',
headers: {
'Cookie': sessionCookie,
},
}).then(res => res.text()).then(textResponse => {
// When initially writing this code I found if cookie payload
// was invalid I got this text response so I added this code to
// handle this, shouldn't happen but good to have an error message
// for this use case
if (textResponse === 'Disallowed Key Characters.') {
return Promise.reject('Invalid request');
}
else {
try {
// Hopefully if we got to this point we can parse the json
const json = JSON.parse(textResponse);
if (json.result === '0') {
return Promise.reject('Unable to get status');
}
else {
return json;
}
} catch (error) {
// If you get this error message I likely have not handled
// a error state that I wasnt aware of
return Promise.reject('Unable to parse response');
}
}
});
}
function setStatus (sessionCookie, mode) {
return new Promise((resolve, reject) => {
if (!sessionCookie || sessionCookie.length === 0) {
reject('Please call getSessionCookie to get your session cookie first');
}
if (mode !== 'arm' && mode !== 'home' && mode !== 'disarm') {
reject('Invalid mode passed to setStatus');
}
resolve(fetch(`${urls.setStatus}${mode}`, {
method: 'POST',
headers: {
'Cookie': sessionCookie,
},
}));
});
}
module.exports = {
getSessionCookie,
getStatus,
setStatus,
}
i'm every new to coding but was able to piece the below together to return the current status of my alarm. the problem is I'm unable to get it to work. based on the above code could someone please tell me what I'm missing, or if I'm going down the wrong rabbit hole....
import requests
import webbrowser
url = “https://www.yalehomesystem.co.uk/homeportal/api/login/check_login”
payload = {‘username’: ‘email#domaim.com’, ‘password’: ‘mypass’}
with requests.session() as s:
# fetch the login page
s.get(url, data=payload)
url1='https://www.yalehomesystem.co.uk/homeportal/api/panel/get_panel_mode'
# post to the login form
r = s.post(url1, data=payload)
print(r.text)
To add more contexts I'm getting the following error
{"result":"0","message":"system.permission_denied","code":"999"}

Related

How to improve sequential promises execution and force fulfillment

This code is being used in a Sveltekit web application.
In the first step I get a user jwt token from an api like : dashboard.example.com/auth/local
and in the second step I'm using the response of the first api call to get full information from an api endpoint like this : example.com/api/users/token
This is an endpoint in an Sveltekit application:
import { json as json$1, error } from '#sveltejs/kit';
import axios from 'axios';
import md5 from 'md5';
import { SITE_ADDRESS } from '$lib/Env';
let userToken;
/** #type {import('#sveltejs/kit').RequestHandler} */
export async function POST({ request }) {
const bodyData = await request.json();
let identifier = bodyData.data.identifier;
let password = bodyData.data.password;
let loginToken = bodyData.data.loginToken;
let newLoginToken = md5(identifier + password + process.env.SECURE_HASH_TOKEN);
let dataResult = await axios
.post(`${import.meta.env.VITE_SITE_API}/auth/local`, {
identifier: identifier,
password: password
})
.then((response) => {
return response.data;
})
.then((response) => {
let userSummaryData = response;
userToken = md5(
userSummaryData.user.username + userSummaryData.user.id + process.env.SECURE_HASH_TOKEN
);
let userCompleteData = axios
.post(`${SITE_ADDRESS}/api/users/${userToken}`, {
data: {
userID: userSummaryData.user.id,
username: userSummaryData.user.username
}
})
.then((response) => {
return {
userJWT: userSummaryData.jwt,
userSummary: userSummaryData.user,
userFullSummary: response.data.userFullSummary
};
});
return userCompleteData;
})
.catch((error) => {
// console.log(' ---- Err ----');
});
if (dataResult && newLoginToken == loginToken) {
return json$1(
{
userJWT: dataResult.userJWT,
userSummary: dataResult.userSummary,
userFullSummary: dataResult.userFullSummary
},
{
headers: {
'cache-control': 'private, max-age=0, no-store'
}
}
);
} else if (dataResult && newLoginToken != loginToken) {
throw error(400, 'Something wrong happened');
}
throw error(401, 'Something wrong happened');
}
This code is work perfectly in localhost. But when I test it on host I get error 401.
and the question is :
Why this works on localhost but doesn't work on the server?
How can I improve this kind of promises (I'd like to use the response of the first api call in the second api call and return both
as a result)

net::ERR_EMPTY_RESPONSE when API request is made in return of react

First off this was working before but when I opened the code for further change to add redux it stopped working.
I am Sending the login Request from Axios to backend API . But when I click on submit button It does not seem to work. Even it does not print the console.log("I am in ") statement. But when I got to the network tab and see the xhr , I see the output attached in image. Last day it was working all of fine. But Now I am getting no response and even not a console statement to see if I am going in Submit form function.
Here Is my code SignIn.js
let submitForm = (e) => {
e.preventDefault();
console.log("I am in "); //button click not printing this statement but axios request is made
let loginDataObject = {
email: formDetails.userEmail,
password: encryptThis(formDetails.LoginPassword)
}
// Axios request
const url = 'http://localhost:5000/api/v1/users/login'
axios({
method: 'post',
url: url,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
data: loginDataObject
})
.then(res => {
const status = res.status;
const userEmail = res.data.data.user.email;
if (status === 200) {
let userObject = {
email: JSON.stringify(userEmail),
tk: JSON.stringify(res.data.token)
}
localStorage.setItem('currentUser', JSON.stringify(userObject));
}
})
.then(() => {
history.push('/dashboard')
})
.catch(err => {
// if password is incorrect
console.log(err);
})
}
return (
<input type="button" onClick={submitForm} className="btn btn-primary mainGreenBtnFullWidth" value="Log In" />
)
```
Most probably it is a network-related error. Based on the console log, it looks like your request doesn't reach the server and you don't have a response to check in your code. You could get similar errors because of a CORS error or DNS misconfigurations.
To catch these kinds of errors, since you don't have a response, you can write an Axios interceptor like this:
axios.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (typeof error.response === "undefined") {
console.log("network error");
window.location.href = "/error-page";
}
if (error.response.status === 401) {
// Authorization error
window.location.href = "/signin";
} else if (error.response.status === 500) {
// Server error
window.location.href = "/500-error";
} else {
return Promise.reject(error);
}
}
);
Of course, this doesn't solve your actual problem, but you can improve the user experience by showing some kind of error.

React-Native dynamically change fetch url

I have a Mobile App that either uses a cloud server or a local server to serve information.
In my App.js I have:
helperUtil.apiURL().then((url) => {
global.API_URL = url;
})
The function does something like:
export async function apiURL() {
try {
var local = await AsyncStorage.getItem('local')
local = (local === 'true')
if(typeof local == 'undefined') return "https://api.website.com";
else if(!local) return "http://192.168.0.6:8080";
else return "https://api.website.com";
}
catch(err) {
return "https://api.website.com";
}
}
Then my fetch command would be:
fetch(global.API_URL+'/page', {
method: 'GET',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer '+this.state.authtoken },
})
I'm running into problems here where the API_URL ends up undefined so I feel like there might be a better solution to this.
Open to any and all suggestions. Thank you.
Insted of seetting url in global obj always use method which return a Promise, and it will return your global object if exist and if not get data from apiURL function. With async/await syntax fetch will be executed only when getAPI promise will be resolved and there will be no situation that url is empty.
const getAPI = () => {
return new Promise((resolve, reject) =>{
if(global.API_URL) {
resolve(global.API_URL)
} else {
helperUtil.apiURL().then((url) => {
global.API_URL = url;
resolve(url)
})
}
});
const fetchFunc = async () => {
const url = await getAPI()
fetch(url+'/page', {
method: 'GET',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer
'+this.state.authtoken },
})
}

Promises with React [duplicate]

This question already has answers here:
What's the difference between returning value or Promise.resolve from then()
(6 answers)
Closed 4 years ago.
I have questions about promises. I'm just starting to deal with them and it's not that easy to understand!
I'm trying to setup an authentication system for my app.
RegisterPage
handleSubmit looks like that:
handleSubmit(event) {
event.preventDefault();
const { user } = this.state;
//some code here
userActions.register(user);
}
UserActions
function register(user) {
userService.register(user)
.then(
user => {
success(user);
},
error => {
failure(error.toString());
}
);
function success(user) { return { type: "REGISTER_SUCCESS", user } }
function failure(error) { return { type: "REGISTER_ERROR", error } }
}
UserService
function register(user) {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(user)
};
return fetch(`/api/users/register`, requestOptions).then(handleResponse);
}
function handleResponse(response) {
return response.text().then(text => {
const data = text && JSON.parse(text);
if (!response.ok) {
const error = (data && data.message) || response.statusText;
return Promise.reject(error);
}
return data;
});
}
Question 1. That code is "working" but not like I want. That way, even if the request success, I still can have error from the server, like duplicate username or something like that. I guess what I want is to return Promise.reject() not just if !response.ok but also if I have errors in the JSON returned right?
function handleResponse(response) {
return response.text().then(text => {
const data = text && JSON.parse(text);
if (!response.ok) {
const error = (data && data.message) || response.statusText;
return Promise.reject(error);
}
else if(data.errors) {
return Promise.reject(data.message);
}
return data;
});
}
Question 2. If everything's fine, should I return data or return Promise.resolve(data)? And why?
Checkout the documentation for fetch here: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful
It seems you should be using .catch() to get server errors and just use throw new Error() for having errors.
You don't really need to use Promise.resolve or Promise.reject.
To help refactor what you have, you can try this
function register(user) {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(user)
};
return fetch(`/api/users/register`, requestOptions).then(handleResponse);
}
function handleResponse(response) {
return response.text()
.then(text => {
if (!response.ok) {
const error = (data && data.message) || response.statusText;
throw new Error(error);
} else {
const data = text && JSON.parse(text);
return data;
}
})
.catch(error => throw new Error(err));
}

How can we maintain user logged in when access token expires and we need to login again to continue as normal user

I'm using Nuxt-axios module with the proxy.
For Error handling, I have common code in
Plugins/axios.js
export default function({ $axios, __isRetryRequest, store, app, redirect , payload , next}) {
$axios.onRequest(config => {
if (app.$cookies.get('at') && app.$cookies.get('rt') && config.url != '/post_login/') {
config.headers.common['Authorization'] = `Bearer ${app.$cookies.get('at')}`;
}
});
$axios.onResponseError(err => {
const code = parseInt(err.response && err.response.status)
let originalRequest = err.config;
if (code === 401) {
originalRequest.__isRetryRequest = true;
store
.dispatch('LOGIN', { grant_type: 'refresh_token', refresh_token: app.$cookies.get('rt')})
.then(res => {
originalRequest.headers['Authorization'] = 'Bearer ' + app.$cookies.get('at');
return app.$axios(originalRequest);
})
.catch(error => {
console.log(error);
});
}
// code for 422 error
if (code == 422) {
throw err.response;
}
});
}
On my page folder index page
Pages/index.vue
<template>
<section>Component data</section>
</template>
<script type="text/javascript">
export default {
async asyncData({ route, store }) {
await store.dispatch('GET_BANNERS');
}
}
</script>
All the API calls are in a stroes/actions.js file.
Now the question is when I refresh the page index.vue first API request will hit and get the response if successful. But now if on first request( 'GET_BANNERS' ) from asyncData and it gets 401 error unauthorized then I'm getting below error
Error: Request failed with status code 401
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
how can I resolve this?
few more questions:
1) When I'm writing common error code in axios, original request on which I have received 401 how can I set data to store again(which we normally do from actions file)?
2) can anyone help with best practice to attach authorization headers and error handle for 400,401,422, etc..
$axios.onResponseError(err => {
const code = parseInt(err.response && err.response.status);
let originalRequest = err.config;
if (code == 401) {
originalRequest.__isRetryRequest = true;
let token = app.$cookies.get('rt');
return new Promise((resolve, reject) => {
let req = $axios
.post(`/login`, { grant_type: 'refresh_token', refresh_token: token })
.then(response => {
if (response.status == 200) {
app.$cookies.set('access', response.data.access_token);
app.$cookies.set('refresh', response.data.refresh_token);
originalRequest.headers['Authorization'] = `Bearer ${
response.data.access_token
}`;
}
resolve(response);
}).catch(e => {
reject("some message");
})
})
.then(res => {
return $axios(originalRequest);
}).catch(e => {
app.router.push('/login');
});
}
});
#canet-robern hope this will solve your prob!!
The error ERR_HTTP_HEADERS_SENT means that you have a bug in your server-side code - hence the error from this bug comes before the HTTP headers.
To handle 4xx errors and retry the Axios request - follow this example:
Vue.prototype.$axios = axios.create(
{
headers:
{
'Content-Type': 'application/json',
},
baseURL: process.env.API_URL
}
);
Vue.prototype.$axios.interceptors.request.use(
config =>
{
events.$emit('show_spin');
let token = getTokenID();
if(token && token.length) config.headers['Authorization'] = token;
return config;
},
error =>
{
events.$emit('hide_spin');
if (error.status === 401) VueRouter.push('/login');
else throw error;
}
);
Vue.prototype.$axios.interceptors.response.use(
response =>
{
events.$emit('hide_spin');
return response;
},
error =>
{
events.$emit('hide_spin');
return new Promise(function(resolve,reject)
{
if (error.config && error.response && error.response.status === 401 && !error.config.__isRetry)
{
myVue.refreshToken(function()
{
error.config.__isRetry = true;
error.config.headers['Authorization'] = getTokenID();
myVue.$axios(error.config).then(resolve,reject);
},function(flag) // true = invalid session, false = something else
{
if(process.env.NODE_ENV === 'development') console.log('Could not refresh token');
if(getUserID()) myVue.showFailed('Could not refresh the Authorization Token');
reject(flag);
});
}
else throw error;
});
}
);

Categories

Resources