Phyks (Lucas Verney)
157382c3b8
When not setting an endpoint protocol scheme at login, "http" was assumed. Changing this to the same protocol as current one, to avoid mixed blocked content. Also prevent multiple submissions of LoginForm.
174 lines
5.0 KiB
JavaScript
174 lines
5.0 KiB
JavaScript
import { push } from "react-router-redux";
|
|
import jsSHA from "jssha";
|
|
import Cookies from "js-cookie";
|
|
|
|
import { CALL_API } from "../middleware/api";
|
|
|
|
export const DEFAULT_SESSION_INTERVAL = 1800 * 1000; // 30 mins default
|
|
|
|
function _cleanEndpoint (endpoint) {
|
|
// Handle endpoints of the form "ampache.example.com"
|
|
if (
|
|
!endpoint.startsWith("//") &&
|
|
!endpoint.startsWith("http://") &&
|
|
!endpoint.startsWith("https://"))
|
|
{
|
|
endpoint = window.location.protocol + "//" + endpoint;
|
|
}
|
|
// Remove trailing slash and store endpoint
|
|
endpoint = endpoint.replace(/\/$/, "");
|
|
return endpoint;
|
|
}
|
|
|
|
function _buildHMAC (password) {
|
|
// Handle Ampache HMAC generation
|
|
const time = Math.floor(Date.now() / 1000);
|
|
|
|
var shaObj = new jsSHA("SHA-256", "TEXT");
|
|
shaObj.update(password);
|
|
const key = shaObj.getHash("HEX");
|
|
|
|
shaObj = new jsSHA("SHA-256", "TEXT");
|
|
shaObj.update(time + key);
|
|
|
|
return {
|
|
time: time,
|
|
passphrase: shaObj.getHash("HEX")
|
|
};
|
|
}
|
|
|
|
export function loginKeepAlive(username, token, endpoint) {
|
|
return {
|
|
type: CALL_API,
|
|
payload: {
|
|
endpoint: endpoint,
|
|
dispatch: [
|
|
null,
|
|
null,
|
|
error => dispatch => {
|
|
dispatch(loginUserFailure(error || "Your session expired… =("));
|
|
}
|
|
],
|
|
action: "ping",
|
|
auth: token,
|
|
username: username,
|
|
extraParams: {}
|
|
}
|
|
};
|
|
}
|
|
|
|
export const LOGIN_USER_SUCCESS = "LOGIN_USER_SUCCESS";
|
|
export function loginUserSuccess(username, token, endpoint, rememberMe, timerID) {
|
|
return {
|
|
type: LOGIN_USER_SUCCESS,
|
|
payload: {
|
|
username: username,
|
|
token: token,
|
|
endpoint: endpoint,
|
|
rememberMe: rememberMe,
|
|
timerID: timerID
|
|
}
|
|
};
|
|
}
|
|
|
|
export const LOGIN_USER_FAILURE = "LOGIN_USER_FAILURE";
|
|
export function loginUserFailure(error) {
|
|
Cookies.remove("username");
|
|
Cookies.remove("token");
|
|
Cookies.remove("endpoint");
|
|
return {
|
|
type: LOGIN_USER_FAILURE,
|
|
payload: {
|
|
error: error
|
|
}
|
|
};
|
|
}
|
|
|
|
export const LOGIN_USER_REQUEST = "LOGIN_USER_REQUEST";
|
|
export function loginUserRequest() {
|
|
return {
|
|
type: LOGIN_USER_REQUEST
|
|
};
|
|
}
|
|
|
|
export const LOGOUT_USER = "LOGOUT_USER";
|
|
export function logout() {
|
|
return (dispatch, state) => {
|
|
const { auth } = state();
|
|
if (auth.timerID) {
|
|
clearInterval(auth.timerID);
|
|
}
|
|
Cookies.remove("username");
|
|
Cookies.remove("token");
|
|
Cookies.remove("endpoint");
|
|
dispatch({
|
|
type: LOGOUT_USER
|
|
});
|
|
};
|
|
}
|
|
|
|
export function logoutAndRedirect() {
|
|
return (dispatch) => {
|
|
dispatch(logout());
|
|
dispatch(push("/login"));
|
|
};
|
|
}
|
|
|
|
export function loginUser(username, passwordOrToken, endpoint, rememberMe, redirect="/", isToken=false) {
|
|
endpoint = _cleanEndpoint(endpoint);
|
|
var time = 0;
|
|
var passphrase = passwordOrToken;
|
|
|
|
if (!isToken) {
|
|
// Standard password connection
|
|
const HMAC = _buildHMAC(passwordOrToken);
|
|
time = HMAC.time;
|
|
passphrase = HMAC.passphrase;
|
|
} else {
|
|
// Remember me connection
|
|
if (passwordOrToken.expires < new Date()) {
|
|
// Token has expired
|
|
return loginUserFailure("Your session expired… =(");
|
|
}
|
|
time = Math.floor(Date.now() / 1000);
|
|
passphrase = passwordOrToken.token;
|
|
}
|
|
return {
|
|
type: CALL_API,
|
|
payload: {
|
|
endpoint: endpoint,
|
|
dispatch: [
|
|
loginUserRequest,
|
|
jsonData => dispatch => {
|
|
if (!jsonData.auth || !jsonData.sessionExpire) {
|
|
return Promise.reject("API error.");
|
|
}
|
|
const token = {
|
|
token: jsonData.auth,
|
|
expires: new Date(jsonData.sessionExpire)
|
|
};
|
|
// Dispatch success
|
|
const timerID = setInterval(
|
|
() => dispatch(loginKeepAlive(username, token.token, endpoint)),
|
|
DEFAULT_SESSION_INTERVAL
|
|
);
|
|
if (rememberMe) {
|
|
const cookiesOption = { expires: token.expires };
|
|
Cookies.set("username", username, cookiesOption);
|
|
Cookies.set("token", token, cookiesOption);
|
|
Cookies.set("endpoint", endpoint, cookiesOption);
|
|
}
|
|
dispatch(loginUserSuccess(username, token, endpoint, rememberMe, timerID));
|
|
// Redirect
|
|
dispatch(push(redirect));
|
|
},
|
|
loginUserFailure
|
|
],
|
|
action: "handshake",
|
|
auth: passphrase,
|
|
username: username,
|
|
extraParams: {timestamp: time}
|
|
}
|
|
};
|
|
}
|