WIP on redux refactor: last commit before client_server.js removal
This commit is contained in:
parent
636ade0273
commit
c36d298f10
2 changed files with 122 additions and 32 deletions
|
@ -3,6 +3,7 @@ import actions from "./storeActions";
|
|||
import axios from "axios";
|
||||
|
||||
class Endpoint {
|
||||
socket = null;
|
||||
axiosInstance = axios.create({
|
||||
baseURL: this.URL,
|
||||
validateStatus: (status) => status >= 200 && status < 300,
|
||||
|
@ -55,6 +56,31 @@ class Endpoint {
|
|||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Performs login
|
||||
* @param {String} usernameOrEmail
|
||||
* @param {String} password
|
||||
* @returns {Promise<Undefined, String[]>} promise that resolves to void and rejects
|
||||
* with user-fiendly errors as a String array
|
||||
*/
|
||||
static login(dispatch, usernameOrEmail, password) {
|
||||
return Endpoint.axiosInstance
|
||||
.post(`${Endpoint.URL}/auth/login`, {
|
||||
usernameOrEmail,
|
||||
password,
|
||||
})
|
||||
.then((res) => {
|
||||
localStorage.setItem("token", res.token);
|
||||
localStorage.setItem("exp", new Date().getTime() + 5 * 60 * 60 * 1000);
|
||||
this.socket = new ServiceSocket(res.data.token);
|
||||
return res.data.token;
|
||||
});
|
||||
}
|
||||
|
||||
static logout() {
|
||||
this.socket.close();
|
||||
this.socket = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an authenticated GET request
|
||||
|
@ -126,19 +152,8 @@ export class RemoteService {
|
|||
*/
|
||||
static login(usernameOrEmail, password) {
|
||||
return (dispatch) => {
|
||||
return Endpoint.axiosInstance
|
||||
.post(`${Endpoint.URL}/auth/login`, {
|
||||
usernameOrEmail,
|
||||
password,
|
||||
})
|
||||
.then((res) => {
|
||||
localStorage.setItem("token", res.token);
|
||||
localStorage.setItem(
|
||||
"exp",
|
||||
new Date().getTime() + 5 * 60 * 60 * 1000
|
||||
);
|
||||
dispatch(actions.loginSuccess(res.token));
|
||||
})
|
||||
return Endpoint.login(dispatch, usernameOrEmail, password)
|
||||
.then((token) => dispatch(actions.loginSuccess(token)))
|
||||
.catch((err) => {
|
||||
console.warn("login error", err);
|
||||
return [
|
||||
|
@ -156,7 +171,7 @@ export class RemoteService {
|
|||
* @param {String} password
|
||||
*/
|
||||
static logout() {
|
||||
return (dispatch) => void dispatch(actions.logout());
|
||||
return (dispatch) => Endpoint.logout.then(void dispatch(actions.logout()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -386,6 +401,71 @@ export class RemoteService {
|
|||
}
|
||||
}
|
||||
|
||||
/** Class to handle connection with the sensor socket */
|
||||
class ServiceSocket {
|
||||
token;
|
||||
authenticated = false;
|
||||
retries = 0;
|
||||
connection;
|
||||
|
||||
static get URL() {
|
||||
const httpURL = new URL(Endpoint.URL);
|
||||
const isSecure = httpURL.protocol === "https:";
|
||||
const protocol = isSecure ? "wss:" : "ws:";
|
||||
const port = httpURL.port || (isSecure ? 443 : 80);
|
||||
return `${protocol}//${httpURL.host}:${port}/sensor-socket`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new sensor socket connection
|
||||
* @param {string} token - The JWT token (needed for authentication)
|
||||
*/
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
this.authenticated = false;
|
||||
}
|
||||
|
||||
_init() {
|
||||
this.connection = new WebSocket(ServiceSocket.URL);
|
||||
|
||||
this.connection.onopen = (_) => {
|
||||
this.connection.send(JSON.stringify({ token: this.token }));
|
||||
};
|
||||
|
||||
this.connection.onmessage = (evt) => {
|
||||
let data = JSON.parse(evt.data);
|
||||
|
||||
if (!this.authenticated) {
|
||||
if (data.authenticated) {
|
||||
this.authenticated = true;
|
||||
this.retries = 0;
|
||||
} else {
|
||||
console.error("socket authentication failed", data);
|
||||
}
|
||||
} else {
|
||||
this.invokeCallbacks(data);
|
||||
}
|
||||
};
|
||||
|
||||
this.connection.onerror = (evt) => {
|
||||
console.warn("socket error", evt);
|
||||
if (this.retries >= 5) {
|
||||
console.error("too many socket connection retries");
|
||||
return;
|
||||
}
|
||||
this.retries++;
|
||||
this._init();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying websocket connection
|
||||
*/
|
||||
close() {
|
||||
this.connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
export class Forms {
|
||||
/**
|
||||
* Attempts to create a new user from the given data.
|
||||
|
|
|
@ -1,22 +1,7 @@
|
|||
import { createStore } from "redux";
|
||||
import { RemoteService } from "./remote";
|
||||
import { createDispatchHook } from "react-redux";
|
||||
import { createStore, applyMiddleware } from "redux";
|
||||
import thunk from "redux-thunk";
|
||||
import actions from "./storeActions";
|
||||
|
||||
const initialToken = localStorage.getItem("token");
|
||||
|
||||
const initialState = {
|
||||
login: {
|
||||
loggedIn: false,
|
||||
token: initialToken ? initialToken : null,
|
||||
},
|
||||
userInfo: null,
|
||||
/** @type {[integer]Room} */
|
||||
rooms: {},
|
||||
/** @type {[integer]Device} */
|
||||
devices: {},
|
||||
};
|
||||
|
||||
function reducer(previousState, action) {
|
||||
let newState = Object.assign({}, previousState);
|
||||
const createOrUpdateRoom = (room) => {
|
||||
|
@ -129,9 +114,34 @@ function reducer(previousState, action) {
|
|||
console.warn(`Action type ${action.type} unknown`, action);
|
||||
}
|
||||
|
||||
console.log("new state: ", newState);
|
||||
return newState;
|
||||
}
|
||||
|
||||
const smartHutStore = createStore(reducer, initialState);
|
||||
function createSmartHutStore() {
|
||||
const token = localStorage.getItem("token");
|
||||
const exp = localStorage.getItem("exp");
|
||||
|
||||
const initialState = {
|
||||
login: {
|
||||
token: token,
|
||||
},
|
||||
userInfo: null,
|
||||
/** @type {[integer]Room} */
|
||||
rooms: {},
|
||||
/** @type {[integer]Device} */
|
||||
devices: {},
|
||||
};
|
||||
|
||||
initialState.login.loggedIn = token && exp > new Date().getTime();
|
||||
if (!initialState.login.loggedIn) {
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("exp");
|
||||
initialState.login.token = null;
|
||||
}
|
||||
|
||||
return createStore(reducer, initialState, applyMiddleware(thunk));
|
||||
}
|
||||
|
||||
const smartHutStore = createSmartHutStore();
|
||||
export default smartHutStore;
|
||||
|
|
Loading…
Reference in a new issue