/*global define */
define(['jquery', 'underscore', 'backbone', 'text!templates/login.html',
'text!templates/alert.html', 'text!templates/loginButtons.html',
'text!templates/loginOptions.html', 'text!templates/login-ldap.html'],
function($, _, Backbone, LoginTemplate, AlertTemplate, LoginButtonsTemplate, LoginOptionsTemplate, LdapLoginTemplate) {
'use strict';
/**
* @class SignInView
* @classcategory Views
* @extends Backbone.View
* @screenshot views/SignInView.png
*/
var SignInView = Backbone.View.extend(
/** @lends SignInView.prototype */{
template: _.template(LoginTemplate),
alertTemplate: _.template(AlertTemplate),
buttonsTemplate: _.template(LoginButtonsTemplate),
loginOptionsTemplate: _.template(LoginOptionsTemplate),
ldapTemplate: _.template(LdapLoginTemplate),
tagName: "div",
className: "sign-in-btns",
ldapError: false,
/* Set to true to only show the LDAP login form */
ldapOnly: false,
/* Set to true if this SignInView is the only thing on the page */
fullPage: false,
/* Set to true if this SignInView is in a modal window */
inPlace: false,
/**
* Set a query string that will be added to the redirect URL
* when the user has logged-in and is returned back to MetacatUI.
* This can be useful to return back to MetacatUI with additional information
* about the state of the app when the user left to sign in.
* @type {string}
* @example
* // This example may tell the view that the register citation modal was open when Sign In was clicked
* "registerCitation=true"
* @default ""
* @since 2.15.0
*/
redirectQueryString: "",
/*A message to display at the top of the view */
topMessage: "",
initialize: function(options){
if(typeof options !== "undefined"){
this.inPlace = options.inPlace;
this.topMessage = options.topMessage;
this.fullPage = options.fullPage;
this.closeButtons = options.closeButtons === false? false : true;
}
},
render: function(){
//Don't render a SignIn view if there are no Sign In URLs configured
if(!MetacatUI.appModel.get("signInUrlOrcid"))
return this;
var view = this;
if(this.inPlace){
this.$el.addClass("hidden modal");
this.$el.attr("data-backdrop", "static");
//Add a message to the top, if supplied
if(typeof this.topMessage == "string")
this.$el.prepend('<p class="center container">' + this.topMessage + '</p>');
else if(typeof this.topMessage == "object")
this.$el.prepend(this.topMessage);
//Copy/paste the contents of the sign-in popup
var signInBtns = $.parseHTML($("#signinPopup").html().trim()),
signInBtnsContainer = $(document.createElement("div")).addClass("center container").html(signInBtns);
signInBtnsContainer.find("a.signin").each(function(i, a){
var url = $(a).attr("href");
var redirectUrl = decodeURIComponent(url.substring( url.indexOf("target=")+7 ));
var urlWithoutHttp = redirectUrl.substring( redirectUrl.indexOf("://") + 3 );
var routeName = urlWithoutHttp.substring( urlWithoutHttp.indexOf("/") + 1 );
if( !routeName ){
redirectUrl = redirectUrl + "signinsuccess";
}
else if( _.contains(MetacatUI.uiRouter.getRouteNames(), MetacatUI.uiRouter.getRouteName(routeName)) ){
redirectUrl = redirectUrl.substring(0, redirectUrl.indexOf(routeName)) + "signinsuccess";
}
url = url.substring(0, url.indexOf("target=")+7) + encodeURIComponent(redirectUrl);
$(a).attr("href", url);
});
signInBtnsContainer.find("h1, h2").remove();
this.$el.append(signInBtnsContainer);
//Remove the accordion widget from the ldap login so it gets displayed as a popup window instead
if( this.$("#signinLdap").length ){
this.$("[href='" + "#signinLdap']").addClass("signin");
this.$(".accordion").removeClass("accordion");
}
this.$el.prepend($(document.createElement("div")).addClass("container").prepend(
$(document.createElement("a")).text("Close").addClass("close").prepend(
$(document.createElement("i")).addClass("icon icon-on-left icon-remove"))));
//Listen for clicks
this.$("a.signin").on("click", function(e){
//Get the link URL and change the target to a special route
e.preventDefault();
var link = e.target;
if(link.nodeName != "A") link = $(link).parents("a");
var url = $(link).attr("href");
//Open up a new small window with this URL to allow the user to login
window.open(url, "Login", "height=600,width=700");
//Listen for successful sign-in
window.listenForSignIn = setInterval(function(){
MetacatUI.appUserModel.checkToken(function(data){
$(".modal.sign-in-btns").modal("hide");
clearInterval(window.listenForSignIn);
if(MetacatUI.appUserModel.get("checked"))
MetacatUI.appUserModel.trigger("change:checked");
else
MetacatUI.appUserModel.set("checked", true);
});
}, 750);
});
if( this.closeButtons ){
this.$("a.close").on("click", function(e){
view.$el.modal("hide");
});
}
else{
this.$(".close").remove();
//Create a sign out link
var divider = document.createElement("hr"),
signOutLink = $(document.createElement("a"))
.addClass("error underline")
.text("Sign Out");
//Add the Sign Out link to the view
this.$(".modal-body").append(divider, signOutLink);
//If we're on the EML211EditorView, then show a warning message that unsaved changes will be lost
if( MetacatUI.appView.currentView && MetacatUI.appView.currentView.type == "EML211Editor" ){
signOutLink.after( $(document.createElement("p"))
.addClass("error")
.text(" Warning! - All your unsaved changes will be lost."));
}
//When the sign out link is clicked, we can just refresh the page.
signOutLink.on("click", function(e){
window.location.reload();
});
}
}
else{
//If it's a full-page sign-in view, then empty it first
if(this.el == MetacatUI.appView.el || this.fullPage){
this.$el.empty();
var container = document.createElement("div");
container.className = "container login";
if( this.ldapOnly ){
var redirectUrl = window.location.origin + window.location.pathname;
redirectUrl = redirectUrl.substring(0, redirectUrl.lastIndexOf("/"));
redirectUrl + "/signinSuccessLdap";
$(container).append(this.ldapTemplate({
redirectUrl: redirectUrl
}));
this.$el.append(container);
//Hide all the other page elements so it's just the login form
$("#Navbar, #HeaderContainer, #Footer").hide();
}
else{
$(container).append(this.buttonsTemplate({
signInUrl: MetacatUI.appModel.get('signInUrlOrcid') + this.getRedirectURL()
}));
this.$el.append(container);
}
}
else{
if( this.ldapOnly ){
var redirectUrl = MetacatUI.root + "/signinSuccessLdap";
this.$el.append(this.ldapTemplate({
redirectUrl: redirectUrl
}));
}
else{
let signInUrl = MetacatUI.appModel.get('signInUrlOrcid') + this.getRedirectURL();
this.$el.append(this.buttonsTemplate({
signInUrl: signInUrl
}));
}
}
//Insert the sign in popup screen once
if(!$("#signinPopup").length){
var target = this.getRedirectURL();
var signInUrl = MetacatUI.appModel.get('signInUrl')? MetacatUI.appModel.get('signInUrl') + target : null;
var signInUrlOrcid = MetacatUI.appModel.get('signInUrlOrcid') ? MetacatUI.appModel.get('signInUrlOrcid') + target : null;
var signInUrlLdap = MetacatUI.appModel.get('signInUrlLdap') ? MetacatUI.appModel.get('signInUrlLdap') + target : null,
redirectUrl = (window.location.href.indexOf("signinldaperror") > -1) ?
window.location.href.replace("signinldaperror", "") : window.location.href;
$("body").append(this.template({
signInUrl: signInUrl,
signInUrlOrcid: signInUrlOrcid,
signInUrlLdap: signInUrlLdap,
ldapLoginForm: this.ldapTemplate({
redirectUrl: redirectUrl
}),
currentUrl: window.location.href,
loginOptions: this.loginOptionsTemplate({ signInUrl: signInUrl }).trim(),
collapseLdap: !MetacatUI.appUserModel.get("errorLogin"),
redirectUrl: redirectUrl
}));
this.setUpPopup();
}
//If there is an error message in the URL, it means authentication has failed
if(this.ldapError){
MetacatUI.appUserModel.failedLdapLogin();
this.failedLdapLogin();
};
}
return this;
},
/*
* This function is executed when LDAP authentication fails in the DataONE portal
*/
failedLdapLogin: function(){
//Insert an error message
this.$("form").before(this.alertTemplate({
classes: "alert-error",
msg: "Incorrect username or password. Please try again."
}));
//If this is a full-page sign-in view, then take the form and insert it into the page
if(this.$el.attr("id") == "Content" && !$("#Content form").length)
$("#Content").html( $("#signinLdap").html() );
//Else, just show the login in the modal window
else if(!this.ldapOnly){
$("#signinPopup").modal("show");
}
//Show the LDAP login form
$('#signinLdap').removeClass("collapse").css("height", "auto");
},
setUpPopup: function(){
var view = this;
//Initialize the modal elements
$("#signupPopup, #signinPopup").modal({
show: false,
shown: function(){
//Update the sign-in URLs so we are redirected back to the previous page after authentication
if( MetacatUI.appModel.get("enableCILogonSignIn") ){
$("a.update-sign-in-url").attr("href", MetacatUI.appModel.get("signInUrl") + encodeURIComponent(window.location.href));
}
$("a.update-orcid-sign-in-url").attr("href", MetacatUI.appModel.get("signInUrlOrcid") + encodeURIComponent(window.location.href));
}
});
},
/**
* Constructs and returns a string of the URL that the user should return to when they are done signing in.
* This URL is sent to the DataONE portal service during login, via the `target` URL attribute. The DataONE
* portal will redirect the user back to the `target` URL when sign in is complete.
* @returns {string}
*/
getRedirectURL: function(){
let redirectURL = window.location.href;
if( this.redirectQueryString && this.redirectQueryString.length ){
let currentQueryString = window.location.search;
//If there is a current query string in the window.location, concatenate the
// new query string properly
if( currentQueryString.length ){
//Exclude the "?" character from the query string, if it is there already
if( this.redirectQueryString.charAt(0) == "?" ){
this.redirectQueryString = this.redirectQueryString.substring(1)
}
//Add the new query string parameters
redirectURL += "&" + this.redirectQueryString;
}
else{
redirectURL += "?" + this.redirectQueryString;
}
}
return redirectURL;
},
onClose: function(){
this.$el.empty();
if(window.listenForSignIn) clearInterval(window.listenForSignIn);
}
});
return SignInView;
});