on login () {
	«Handle logging in to the site.
	«Changes:
		«9/10/03; 12:43:03 PM by AEG
			«Redirect to SSL, change POST action to SSL and add external authentication.
		«4/18/03; 3:41:39 PM by JES
			«When getting the email address out of the postArgs table, call string.trimWhiteSpace on it in case the user accidentally added a space.
		«9/3/02; 3:07:02 AM by JES
			«Don't redirect to the home page if we just changed our password -- we want confirmation.
		«9/12/01; 3:48:31 PM by PBS
			«Support for expiring cookies at end of session.
		«03/20/01; 10:34:38 PM by PBS
			«The password check was not case-sensitive, but it needs to be, because everywhere else the password is a case-sensitive check.
			«Also: when setting the cookie, don't use the email address as typed into the form; use the name of the person's membership record.
		«01/31/01; 4:36:17 PM by PBS
			«Removed the maxLength restriction for the email address.
		«2000:
			«04/10/00; 3:48:39 PM by PBS
				«Major re-write for efficiency. Also now supports the new membership cookies format.
			«04/21/00; 2:45:20 AM by JES
				«Localized.
			«05/01/00; 3:06:33 PM by JES
				«Changed getString calls to use a replacement table address instead of a list.
			«08/07/00; 9:13:47 PM by PBS
				«Call manilaSuite.sendMail rather than tcp.sendMail.
		«1999:
			«07/6/99; 8:08:55 AM by DW
				«When the user enters a mail address and an empty password, we send the password to the mail address. This is not an error, it's part of the standard interface.
				«Changed the error color from maroon to red to be consistent with other sites, and other parts of our sites.
			«10/30/99; 3:59:25 PM by PBS
				«Don't set table and font colors in the login form, there's no need for that. They should just pick up the colors from the page.
				«Code clean-up. Removed some duplicated code.
			«12/26/99; 5:21:15 PM by PBS
				«Commented out an unneccesary call to fileMenu.saveMyRoot, which should boost performance.
	
	local (pta = html.getPageTableAddress ());
	local (groupName = pta^.defaultMembershipGroup);
	local (htmlText = "", indentLevel = 0);
	local (defaultMailAddress = "");
	local (flPost = string.lower (pta^.method) == "post");
	local (flExpireAtEndOfSession);

        if mit.extAuth.requiresSsl() {
		mit.sslHelper.maybeRedirectToSsl(pta)};
	
	bundle { //PBS 09/12/01: get pref for cookie expiration
		if not defined (pta^.newsSite^.flCookiesExpireAtEndOfSession) {
			pta^.newsSite^.flCookiesExpireAtEndOfSession = false};
		flExpireAtEndOfSession = pta^.newsSite^.flCookiesExpireAtEndOfSession};
	
	pta^.title = manilaSuite.getString ("members.loginPageTitle"); //4/21/00 JES: localized
	pta^.meta = "<META HTTP-EQUIV=\"Expires\" CONTENT=\"Mon, 01 Jan 1990 01:00:00 GMT\">";
	
	on add (s) {
		htmlText = htmlText + string.filledString ('\t', indentLevel) + s + cr;};
	
	bundle { //add the top of the page
		«4/21/00; 2:31:43 AM by JES: localized instructions
		add (manilaSuite.getString ("members.loginPageInstructions"));
		if defined (pta^.newsSite^.flMembership) and pta^.newsSite^.flMembership {
			local (replacementTable); new (tableType, @replacementTable); // 05/01/00 JES: use replacement table instead of a list
			replacementTable.url = pta^.urls^.memberSignup;
			add (manilaSuite.getString ("members.loginPageNotMember", @replacementTable) + "<p>")}};
	
	on logonForm () { //build form (cribbed from mainResponder.members.logonForm)
		add ("<table border=\"0\"><tr><td>"); indentLevel++;
		add ("<form action=\"" + mit.sslHelper.sslUrl(pta^.url) + "\" method=\"POST\">"); indentLevel++;
		add ("<table cellpadding=\"4\" cellspacing=\"0\" border=\"0\">"); indentLevel++;
		
		add ("<tr>"); indentLevel++;
		add ("<td>" + manilaSuite.getString ("members.emailAddressPrompt") + "</td>"); // 4/21/00 JES: localized
		add ("<td> <input name=\"mailAddress\" value=\"" + defaultMailAddress + "\" size=\"30\"></td>"); //PBS 01/31/01: removed the maxLength restriction
		add ("</tr>"); indentLevel--;
		
		add ("<tr>"); indentLevel++;
		add ("<td>" + manilaSuite.getString ("members.passwordPrompt") + "</td>"); // 4/21/00 JES: localized
		add ("<td> <input type=\"password\" name=\"password\" size=\"30\" maxlength=\"60\"></td>");
		add ("</tr>"); indentLevel--;
		
		bundle { //PBS 09/12/01: add Remember Login checkbox
			if flExpireAtEndOfSession {
				add ("<tr>"); indentLevel++;
				add ("<td>Remember Login?</td>");
				add ("<td><input type=\"checkbox\" name=\"rememberLogin\"></td>");
				add ("</tr>"); indentLevel--}};
		
		add ("<tr>"); indentLevel++;
		add ("<td> </td>");
		add ("<td align=\"right\"><input type=\"submit\" value=\"" + manilaSuite.getString ("members.loginButton") + "\"></td>"); // 4/21/00 JES: localized
		add ("</tr>"); indentLevel--;
		
		add ("</table>"); indentLevel--;
		
		bundle { //add the referer
			local (referer);
			if defined (pta^.postArgs.referer) {
				referer = pta^.postArgs.referer}
			else {
				if pta^.searchArgs != "" and pta^.searchArgs beginsWith "http://" {
					referer = pta^.searchArgs}
				else {
					if defined (pta^.requestHeaders.referer) {
						referer = pta^.requestHeaders.referer}
					else {
						referer = pta^.urls^.newsHome}}};
			add ("<input type=\"hidden\" name=\"referer\" value=\"" + referer+ "\">")};
		
		add ("</form>"); indentLevel--;
		add ("</td></tr></table>"); indentLevel--};
	
	if flPost { //handle login command
		local (adrMembers = mainResponder.members.getMembershipTable (groupName));
		local (adrUsers = @adrMembers^.users);
		local (myCookieName = adrMembers^.cookieName);
		
		bundle { //PBS 09/12/01: find out if user wants the login to be remembered
			if defined (pta^.postArgs.rememberLogin) {
				if string.lower (pta^.postArgs.rememberLogin) == "on" {
					flExpireAtEndOfSession = false}}};
		
		on sendCookie () {
			local (memberKey = nameOf (adrUser^)); //)PBS 03/20/01: don't use the username as typed into the form, use the name of the person's membership record
			mainResponder.members.setCookie (memberKey, password, adrMembers, pta, groupName, flExpireAtEndOfSession); //PBS 09/12/01: send flExpireAtEndOfSession parameter
			adrUser^.timeReceivedCookie = clock.now ();
			add (manilaSuite.getString ("members.youHaveBeenSentTheCookie"))}; // 4/21/00 JES: localized
		
		local (mailAddress = string.trimWhiteSpace (pta^.postArgs.mailAddress));
		local (password = pta^.postArgs.password);
		local (adrUser = @adrUsers^.[mailAddress]);
		local (replacementTable); new (tableType, @replacementTable); // 05/01/00 JES: use replacement table instead of a list
		replacementTable.mailAddress = mailAddress;
		if not defined (adrUser^) {
			add ("<font color=\"red\">" + manilaSuite.getString ("members.cantLoginNotMemberError", @replacementTable) + "</font><p>"); // 4/21/00 JES: localized
			logonForm ();
			htmlText = manilaSuite.unTaint (htmlText); //no curly brace macros in this text
			return (htmlText)};
		
		if mit.extAuth.isExternal(mailAddress) {
			if mit.extAuth.isValidAccount(mailAddress,password) {
				bundle { //generate a dummy local password to make session cookies work, 9/10/03 by AG
					password = "";
					local (i);
					for i = 1 to 12 {
						password = password + char ( random ('A', 'Z'))};
					adrUser^.password = password}}
			else {
				add ("<font color=\"red\">" + manilaSuite.getString ("members.cantLoginIncorrectPassword", @replacementTable) + "</font><p>"); // 4/21/00 JES: localized
				defaultMailAddress = mailAddress;
				logonForm ();
				htmlText = manilaSuite.unTaint (htmlText); //no curly brace macros in this text
				return (htmlText)}}
		else {
			if adrUser^.password != password { //PBS 03/20/01: case sensitive check
				if password == "" { //mail the password to the user, 7/6/99; 8:02:22 AM by DW
					«tcp.sendMail (mailAddress, "Password", adrUser^.password, pta^.newsSite^.emailConfirmationSender)
					manilaSuite.sendMail (mailAddress, "Password", adrUser^.password, pta^.newsSite^.emailConfirmationSender); //PBS 08/07/00: call manilaSuite.sendMail
					add ("<font color=\"red\">" + manilaSuite.getString ("members.passwordMailedTo", @replacementTable) + "</font><p>")} // 4/21/00 JES: localized
				else {
					add ("<font color=\"red\">" + manilaSuite.getString ("members.cantLoginIncorrectPassword", @replacementTable) + "</font><p>")}; // 4/21/00 JES: localized
				defaultMailAddress = mailAddress;
				logonForm ();
				htmlText = manilaSuite.unTaint (htmlText); //no curly brace macros in this text
				return (htmlText)}};
		
		sendCookie ();
		
		local (siteUrl = pta^.ftpSite^.url);
		local (referer = pta^.postArgs.referer);
		local (lowerReferer = string.lower (referer));
		if not (lowerReferer endsWith "/changepassword") {
			case true {
				lowerReferer contains "/signout";
				lowerReferer contains "/signup";
				lowerReferer contains "/member"; //PBS 07/05/00: check for /member, not /members
				lowerReferer contains "/admin" {
					referer = pta^.urls^.newsHome}}};
		mainResponder.redirect (referer)}
	else { //build the logon form
		bundle { //handle the case where the member is already logged in
			if defined (pta^.adrMemberInfo) { //PBS 04/10/00: is this an already logged-in member?
				if defined (pta^.adrMemberInfo^) {
					local (memberKey = nameOf (pta^.adrMemberInfo^));
					memberKey = string.replace (memberKey, "@", "\\@");
					local (name = memberKey);
					if defined (pta^.adrMemberInfo^.personalInfo.name) {
						local (realName = string.trimWhiteSpace (pta^.adrMemberInfo^.personalInfo.name));
						if realName != "" {
							name = realName + " (" + memberKey + ")"}};
					local (replacementTable); new (tableType, @replacementTable); // 05/01/00 JES: use replacement table instead of a list
					replacementTable.name = name;
					htmlText = manilaSuite.getString ("members.alreadyLoggedInAs", @replacementTable); // 4/21/00 JES: localized
					return (manilaSuite.unTaint (htmltext))}}};
		
		logonForm ()};
	
	htmlText = manilaSuite.unTaint (htmlText); //no curly brace macros in this text
	
	return (htmlText)}}