opds-web-client
Version:
100 lines (99 loc) • 5.2 kB
JavaScript
var DataFetcher_1 = require("./DataFetcher");
var actions_1 = require("./actions");
// see Redux Middleware docs:
// http://redux.js.org/docs/advanced/Middleware.html
var BASIC_AUTH = "http://opds-spec.org/auth/basic";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = function (store) { return function (next) { return function (action) {
var fetcher = new DataFetcher_1.default();
var actions = new actions_1.default(fetcher);
if (typeof action === "function") {
return new Promise(function (resolve, reject) {
next(actions.hideBasicAuthForm());
var result = next(action);
if (result && result.then) {
result.then(resolve).catch(function (err) {
if (err.status === 401) {
var error = void 0;
var data_1;
// response might not be JSON
try {
data_1 = JSON.parse(err.response);
}
catch (e) {
reject(err);
return;
}
if (err.headers && err.headers.has("www-authenticate")) {
// browser's default basic auth form was shown,
// so don't show ours
reject(err);
}
else {
// clear any invalid credentials
var usedBasicAuth = !!fetcher.getBasicAuthCredentials();
if (usedBasicAuth) {
// 401s resulting from wrong username/password return
// problem detail documents, not auth documents
error = data_1.title;
store.dispatch(actions.clearBasicAuthCredentials());
}
// find provider with basic auth method
var provider = data_1.providers && Object.keys(data_1.providers).find(function (key) {
return Object.keys(data_1.providers[key].methods).indexOf(BASIC_AUTH) !== -1;
});
if (usedBasicAuth ||
provider) {
var callback = function () {
// use dispatch() instead of next() to start from the top
store.dispatch(action).then(function (blob) {
resolve(blob);
}).catch(reject);
};
var title = void 0, labels = void 0;
// if previous basic auth failed, we have to get title and
// labels from store, instead of response data
if (usedBasicAuth) {
var state = store.getState();
title = state.auth.title;
labels = {
login: state.auth.loginLabel,
password: state.auth.passwordLabel
};
}
else {
title = data_1.name;
labels = data_1.providers[provider].methods[BASIC_AUTH].labels;
}
next(actions.closeError());
next(actions.showBasicAuthForm(callback, labels, title, error));
}
else {
// no provider found with basic auth method
// currently this custom response will not make it to the user,
// becuase the fetch error has already been dispatched by
// fetchCollectionFailure, fetchBookFailure, etc
next(actions.hideBasicAuthForm());
reject({
status: 401,
response: "Authentication is required but no compatible authentication method was found.",
url: err.url
});
}
}
}
else {
next(actions.hideBasicAuthForm());
reject(err);
}
});
}
}).catch(function (err) {
// this is where we could potentially dispatch a custom auth error action
// displaying a more informative error
});
}
next(actions.hideBasicAuthForm());
next(action);
}; }; };
;