0
|
1
|
|
2 package nabble.view.web.more;
|
|
3
|
|
4 import fschmidt.db.DbDatabase;
|
|
5 import fschmidt.util.mail.MailAddress;
|
|
6 import fschmidt.util.servlet.CanonicalUrl;
|
|
7 import nabble.model.Db;
|
|
8 import nabble.model.Message;
|
|
9 import nabble.model.ModelException;
|
|
10 import nabble.model.ModelHome;
|
|
11 import nabble.model.Site;
|
|
12 import nabble.model.User;
|
|
13 import nabble.naml.compiler.Template;
|
|
14 import nabble.naml.compiler.TemplatePrintWriter;
|
|
15 import nabble.naml.namespaces.BasicNamespace;
|
|
16 import nabble.view.lib.Jtp;
|
|
17 import nabble.view.lib.NewSiteMail;
|
|
18 import nabble.view.lib.Permissions;
|
|
19 import nabble.view.lib.Shared;
|
|
20 import nabble.view.lib.UrlMappable;
|
|
21 import nabble.view.lib.Recaptcha;
|
|
22 import nabble.view.web.app.Languages;
|
|
23 import nabble.view.web.template.NabbleNamespace;
|
|
24
|
|
25 import javax.servlet.ServletException;
|
|
26 import javax.servlet.http.HttpServlet;
|
|
27 import javax.servlet.http.HttpServletRequest;
|
|
28 import javax.servlet.http.HttpServletResponse;
|
|
29 import java.io.IOException;
|
|
30 import java.io.PrintWriter;
|
|
31 import java.io.StringWriter;
|
|
32 import java.util.Collections;
|
|
33 import java.util.HashMap;
|
|
34 import java.util.Map;
|
|
35 import java.util.regex.Matcher;
|
|
36 import java.util.regex.Pattern;
|
|
37
|
|
38
|
|
39 public final class ForumStart extends HttpServlet implements UrlMappable, CanonicalUrl {
|
|
40
|
|
41 private static final Pattern URL_PATTERN = Pattern.compile("/free-(forum|gallery|newspaper|blog|mailing-list)\\.html$");
|
|
42
|
|
43 public static String url(String what) {
|
|
44 return Jtp.defaultContextUrl() + path(what);
|
|
45 }
|
|
46
|
|
47 public static String path(String what) {
|
|
48 return "/free-" + what + ".html";
|
|
49 }
|
|
50
|
|
51 public String getCanonicalUrl(HttpServletRequest request) {
|
|
52 return url( request.getParameter("what") );
|
|
53 }
|
|
54
|
|
55 public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) {
|
|
56 Matcher m = URL_PATTERN.matcher(mappedUrl);
|
|
57 if( !m.find() )
|
|
58 throw new RuntimeException();
|
|
59 Map<String,String[]> params = new HashMap<String,String[]>();
|
|
60 String what = m.group(1);
|
|
61 params.put("what",new String[]{what});
|
|
62 return params;
|
|
63 }
|
|
64
|
|
65 public Pattern getUrlPattern() {
|
|
66 return URL_PATTERN;
|
|
67 }
|
|
68
|
|
69 protected void service(HttpServletRequest request,HttpServletResponse response)
|
|
70 throws ServletException, IOException
|
|
71 {
|
|
72 build(request, response, Collections.<String,String>emptyMap(), Collections.<String,String>emptyMap());
|
|
73 }
|
|
74
|
|
75 private static void build(HttpServletRequest request,HttpServletResponse response, Map<String,String> values, Map<String,String> errors)
|
|
76 throws ServletException, IOException
|
|
77 {
|
|
78 PrintWriter out = response.getWriter();
|
|
79 String what = request.getParameter("what");
|
|
80 if (what == null)
|
|
81 what = "Forum";
|
|
82 else if ("mailing-list".equals(what))
|
|
83 what = "Mailing List";
|
|
84 else
|
|
85 what = Jtp.capitalize(what);
|
|
86
|
|
87 String imgName = what.toLowerCase();
|
|
88 if ("Mailing List".equals(what))
|
|
89 imgName = "mailing-list";
|
|
90
|
|
91
|
|
92 out.print( "\r\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n <head>\r\n " );
|
|
93 Shared.head(request,response);
|
|
94 out.print( "\r\n <title>Nabble - Free " );
|
|
95 out.print( (what) );
|
|
96 out.print( " Setup</title>\r\n <meta name=\"robots\" content=\"noindex\"/>\r\n <META NAME=\"description\" CONTENT=\"Setting up a free " );
|
|
97 out.print( (what.toLowerCase()) );
|
|
98 out.print( " on Nabble is quick and easy. Fill in one simple form and you are done.\">\r\n <META NAME=\"keywords\" CONTENT=\"free " );
|
|
99 out.print( (what.toLowerCase()) );
|
|
100 out.print( ", hosted " );
|
|
101 out.print( (what.toLowerCase()) );
|
|
102 out.print( ", simple, embeddable " );
|
|
103 out.print( (what.toLowerCase()) );
|
|
104 out.print( ", customizable\">\r\n " );
|
|
105 /*Shared.canonical(request, response);*/
|
|
106 out.print( "\r\n <style type=\"text/css\">\r\n div.center-content {\r\n margin:0px auto;\r\n margin-bottom: 3em;\r\n }\r\n td.column1 {\r\n text-align:right;\r\n width:7em;\r\n white-space:nowrap;\r\n }\r\n input[type=text],input[type=password] {\r\n padding:.4em 0;\r\n }\r\n div.field-title {\r\n margin-top:.3em;\r\n }\r\n .important { font-weight:bold }\r\n label { vertical-align:-15%; }\r\n </style>\r\n <script type=\"text/javascript\">\r\n $(document).ready(function() {\r\n $('#username').focus();\r\n });\r\n\r\n function singleFormSubmit(f) {\r\n if (f.done)\r\n return false;\r\n f.done = true;\r\n $('#submit-btn').hide();\r\n var $div = $('#wait-message');\r\n function loading1() { $div.fadeTo(300,0.3,loading2); };\r\n function loading2() { $div.fadeTo(300,1,loading1); };\r\n loading1();\r\n return true;\r\n };\r\n </script>\r\n " );
|
|
107 out.print( ( Recaptcha.JS ) );
|
|
108 out.print( "\r\n </head>\r\n <body style=\"text-align:center\">\r\n " );
|
|
109 Shared.minHeaderGlobal(request,response);
|
|
110 out.print( "\r\n\r\n <div class=\"center-content\">\r\n <img src=\"/images/logo_nabble_home.png\" border=\"0\" alt=\"Nabble - free forums for everyone\"/><br />\r\n <h1 style=\"color:#979797\">Start Your " );
|
|
111 out.print( (what) );
|
|
112 out.print( "</h1>\r\n\r\n " );
|
|
113 if (errors.size() > 0) {
|
|
114 out.print( "\r\n <div class=\"error-message important\" style=\"margin:1em;padding:.5em 0\">\r\n " );
|
|
115 String generic = errors.get("generic");
|
|
116 out.print( "\r\n " );
|
|
117 out.print( (generic != null? generic : errors.size() > 0? "Please check the errors below" : "") );
|
|
118 out.print( "\r\n </div>\r\n " );
|
|
119 }
|
|
120 out.print( "\r\n\r\n <form action=\"/more/ForumStart$Save.jtp\" method=\"post\" accept-charset=\"UTF-8\" onsubmit=\"return singleFormSubmit(this)\">\r\n <input type=\"hidden\" name=\"type\" value=\"" );
|
|
121 out.print( (what.toLowerCase().replace(" ","")) );
|
|
122 out.print( "\" />\r\n <input type=\"hidden\" name=\"what\" value=\"" );
|
|
123 out.print( (what) );
|
|
124 out.print( "\" />\r\n\r\n <div style=\"text-align:left;width:50em;margin:0 auto\">\r\n <div style=\"border-bottom:2px solid #eeeeee;padding:1em\">\r\n <div class=\"weak-color\" style=\"width:12em;text-align:center;float:left\">\r\n <div style=\"font-weight:bold\">Account</div>\r\n <img src=\"/images/account.png\" width=\"84\" height=\"45\"/>\r\n <div style=\"margin-top:1em;font-size:80%\">\r\n You will receive an email with a link to activate your account\r\n </div>\r\n </div>\r\n <table>\r\n <tr>\r\n <td class=\"column1\"><div class=\"second-font field-title\">User Name</div></td>\r\n <td><input type=\"text\" id=\"username\" size=\"35\" maxlength=\"30\" name=\"username\" value=\"" );
|
|
125 out.print( (Jtp.hideNull(values.get("username"))) );
|
|
126 out.print( "\" /></td>\r\n <td class=\"important\">" );
|
|
127 out.print( (errors.containsKey("username")? errors.get("username"):"") );
|
|
128 out.print( "</td>\r\n </tr>\r\n <tr>\r\n <td class=\"column1\"><div class=\"second-font field-title\">Email</div></td>\r\n <td><input type=\"text\" size=\"35\" maxlength=\"60\" name=\"email\" value=\"" );
|
|
129 out.print( (Jtp.hideNull(values.get("email"))) );
|
|
130 out.print( "\"/></td>\r\n <td class=\"important\">" );
|
|
131 out.print( (errors.containsKey("email")? errors.get("email"):"") );
|
|
132 out.print( "</td>\r\n </tr>\r\n <tr>\r\n <td class=\"column1\"><div class=\"second-font field-title\">Password</div></td>\r\n <td><input type=\"password\" size=\"35\" maxlength=\"15\" name=\"password\" value=\"" );
|
|
133 out.print( (Jtp.hideNull(values.get("password"))) );
|
|
134 out.print( "\"/></td>\r\n <td class=\"important\">" );
|
|
135 out.print( (errors.containsKey("password")? errors.get("password"):"") );
|
|
136 out.print( "</td>\r\n </tr>\r\n <tr>\r\n <td class=\"column1\"><input type=\"checkbox\" id=\"terms\" name=\"terms\" value=\"y\" " );
|
|
137 out.print( ("y".equals(values.get("terms"))?"checked":"") );
|
|
138 out.print( " /></td>\r\n <td colspan=2><label for=\"terms\">I have read and I agree to Nabble's <a href=\"" );
|
|
139 out.print( (Jtp.termsUrl(true)) );
|
|
140 out.print( "\">Terms of Use</a>.</label></td>\r\n </tr>\r\n </table>\r\n </div>\r\n\r\n <div style=\"padding:1em;overflow:hidden\">\r\n <div class=\"weak-color\" style=\"width:12em;text-align:center;float:left;height:15em\">\r\n <div style=\"font-weight:bold\">" );
|
|
141 out.print( (what) );
|
|
142 out.print( "</div>\r\n <img src=\"/images/homepage/" );
|
|
143 out.print( (imgName) );
|
|
144 out.print( ".png\" alt=\"Free " );
|
|
145 out.print( (what.toLowerCase()) );
|
|
146 out.print( "\">\r\n </div>\r\n <table>\r\n <tr>\r\n <td class=\"column1\"><div class=\"second-font field-title\">Language</div></td>\r\n <td>\r\n <select name=\"lang\">\r\n " );
|
|
147 for( Map.Entry<String,String> entry : Languages.languages.entrySet() ) {
|
|
148 out.print( "\r\n " );
|
|
149 String lang = request.getParameter("lang");
|
|
150 out.print( "\r\n " );
|
|
151 boolean isEnglish = entry.getKey().equals("none");
|
|
152 out.print( "\r\n " );
|
|
153 boolean isSelected = (lang == null && isEnglish) || entry.getKey().equals(lang);
|
|
154 out.print( "\r\n <option value=\"" );
|
|
155 out.print( (entry.getKey()) );
|
|
156 out.print( "\" " );
|
|
157 out.print( (isSelected?"selected=\"true\"":"") );
|
|
158 out.print( ">" );
|
|
159 out.print( (entry.getValue()) );
|
|
160 out.print( "</option>\r\n " );
|
|
161 }
|
|
162 out.print( "\r\n </select>\r\n </td>\r\n <td></td>\r\n </tr>\r\n <tr>\r\n <td colspan=\"3\" style=\"height:.6em\"></td>\r\n </tr>\r\n <tr>\r\n <td class=\"column1\"><div class=\"second-font field-title\">" );
|
|
163 out.print( (what) );
|
|
164 out.print( " Name</div></td>\r\n <td><input type=\"text\" name=\"subject\" size=\"30\" maxlength=\"80\" value=\"" );
|
|
165 out.print( (Jtp.hideNull(values.get("subject"))) );
|
|
166 out.print( "\"/></td>\r\n <td class=\"important\">" );
|
|
167 out.print( (errors.containsKey("subject")? errors.get("subject"):"") );
|
|
168 out.print( "</td>\r\n </tr>\r\n <tr>\r\n <td colspan=3 style=\"padding:.4em 0 0 .6em\">\r\n <div class=\"second-font field-title\">Description <span class=\"weak-color\" style=\"font-weight:normal;\">(optional)</span></div>\r\n <textarea rows=\"7\" name=\"message\" wrap=\"SOFT\" style=\"width:28em\">" );
|
|
169 out.print( (Jtp.hideNull(values.get("message"))) );
|
|
170 out.print( "</textarea>\r\n <br>" );
|
|
171 out.print( ( Recaptcha.DIV ) );
|
|
172 out.print( "\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n <div class=\"weak-color\" style=\"margin-top:.5em;text-align:center;\">\r\n <input id=\"submit-btn\" type=\"submit\" name=\"save\" value=\"Create " );
|
|
173 out.print( (what) );
|
|
174 out.print( "\" style=\"padding:.5em .8em;font-size:110%;font-weight:bold\"/>\r\n <div id=\"wait-message\" class=\"important invisible\" style=\"margin:.1em 0\">Creating " );
|
|
175 out.print( (what) );
|
|
176 out.print( "... Please wait</div>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n\r\n " );
|
|
177 Shared.footer(request,response);
|
|
178 out.print( "\r\n " );
|
|
179 Shared.analytics(request,response);
|
|
180 out.print( "\r\n </body>\r\n</html>\r\n" );
|
|
181
|
|
182 }
|
|
183
|
|
184 public static class Save extends HttpServlet {
|
|
185
|
|
186 private static String get(String name, HttpServletRequest request) {
|
|
187 String s = request.getParameter(name);
|
|
188 return s == null? null : s.trim();
|
|
189 }
|
|
190
|
|
191 protected void service(HttpServletRequest request, HttpServletResponse response)
|
|
192 throws ServletException, IOException
|
|
193 {
|
|
194 String username = get("username", request);
|
|
195 String email = get("email", request);
|
|
196 String password = get("password", request);
|
|
197 boolean agreed = "y".equals(get("terms", request));
|
|
198 String subject = get("subject", request);
|
|
199 String message = get("message", request);
|
|
200
|
|
201 Map<String,String> errors = new HashMap<String,String>();
|
|
202 if (username == null || username.trim().length() == 0)
|
|
203 errors.put("username", "required");
|
|
204 if (email == null || email.length() == 0)
|
|
205 errors.put("email", "required");
|
|
206 else if (!new MailAddress(email).isValid())
|
|
207 errors.put("email", "invalid email");
|
|
208 if (password == null || password.length() < 4)
|
|
209 errors.put("password", "too short");
|
|
210 if (!agreed)
|
|
211 errors.put("generic", "You must agree to the Terms and Conditions");
|
|
212 if (subject == null || subject.length() == 0)
|
|
213 errors.put("subject", "required");
|
|
214
|
|
215 String type = get("type", request);
|
|
216 type = "newspaper".equals(type)? "news" : type;
|
|
217
|
|
218 String extraMessage = "";
|
|
219 if ("mailinglist".equals(type)) {
|
|
220 type = "forum";
|
|
221 StringBuilder m = new StringBuilder();
|
|
222 m.append("\n\nMailing List Options\n");
|
|
223 m.append("Click \"Options > Subscribe via email\" to subscribe to this mailing list;\n");
|
|
224 m.append("Click \"Options > Post by email...\" to get the email address of this mailing list;\n");
|
|
225 m.append("You can post messages via email or through the forum interface below;\n");
|
|
226 m.append("All web posts and emails are archived here.");
|
|
227 extraMessage = m.toString();
|
|
228 }
|
|
229
|
|
230 if (errors.isEmpty()) {
|
|
231 DbDatabase db = Db.dbGlobal();
|
|
232 db.beginTransaction();
|
|
233 try {
|
|
234 Recaptcha.check(request);
|
|
235 Site site = ModelHome.newSite(type,subject, message + extraMessage, Message.Format.TEXT, email, username);
|
|
236 Permissions.addToGroup( (User)site.getRootNode().getOwner(), Permissions.ADMINISTRATORS_GROUP );
|
|
237 String key = site.newRegistration(email,password,username,"/");
|
|
238 db.commitTransaction();
|
|
239
|
|
240 // Track spam activities by IP
|
|
241 ModelHome.setRemoteAddr(site, Jtp.getClientIpAddr(request));
|
|
242
|
|
243 site = site.getGoodCopy();
|
|
244
|
|
245 String lang = request.getParameter("lang");
|
|
246 if (!"none".equals(lang)) {
|
|
247 site.setModuleEnabled(lang, true);
|
|
248 site = site.getGoodCopy();
|
|
249 }
|
|
250
|
|
251 sendRegisterMail(site, email, key);
|
|
252 NewSiteMail.send(site, request, response);
|
|
253 response.sendRedirect(site.getBaseUrl()+"/more/ForumStart$Redirection.jtp");
|
|
254 return;
|
|
255 } catch(ModelException e) {
|
|
256 errors.put("generic", e.getMessage());
|
|
257 } finally {
|
|
258 db.endTransaction();
|
|
259 }
|
|
260 }
|
|
261
|
|
262 Map<String,String> values = new HashMap<String,String>();
|
|
263 values.put("username", username);
|
|
264 values.put("email", email);
|
|
265 values.put("password", password);
|
|
266 values.put("terms", agreed?"y":"");
|
|
267 values.put("subject", subject);
|
|
268 values.put("message", message);
|
|
269 build(request, response, values, errors);
|
|
270 }
|
|
271 }
|
|
272
|
|
273 /** Sets cookies in the site domain */
|
|
274 public static class Redirection extends HttpServlet {
|
|
275
|
|
276 protected void service(HttpServletRequest request, HttpServletResponse response)
|
|
277 throws ServletException, IOException
|
|
278 {
|
|
279 Site site = Jtp.getSite(request);
|
|
280 Shared.javascriptRedirect(request, response, Jtp.url(site.getRootNode()), "Nabble.setVar('appnotice','true');");
|
|
281 }
|
|
282 }
|
|
283
|
|
284 public static void sendRegisterMail(Site site, String email, String key) {
|
|
285 Map<String,Object> args = new HashMap<String,Object>();
|
|
286 args.put("email",email);
|
|
287 args.put("next_url","/");
|
|
288 args.put("key",key);
|
|
289 Template template = site.getTemplate( "send_registration_email",
|
|
290 BasicNamespace.class, NabbleNamespace.class
|
|
291 );
|
|
292 template.run( TemplatePrintWriter.NULL, args,
|
|
293 new BasicNamespace(template), new NabbleNamespace(site)
|
|
294 );
|
|
295 }
|
|
296 }
|
|
297
|