hosted/index.php hosted/js hosted/skins lib/client lib/functions.php lib/hosted lib/recaptchalib.php public_html/index.php public_html/js public_html/skins
Aleksander Machniak
machniak at kolabsys.com
Thu Sep 27 09:28:02 CEST 2012
dev/null |binary
hosted/index.php | 11
hosted/js | 1
hosted/js/jquery.min.js | 1
hosted/js/kolab_admin.js | 1
hosted/js/kolab_hosted.js | 120 ------
hosted/skins | 1
hosted/skins/default/hosted.css | 44 --
hosted/skins/default/images/error.png | 1
hosted/skins/default/images/favicon.png | 1
hosted/skins/default/images/info.png | 1
hosted/skins/default/images/loading.gif | 1
hosted/skins/default/style.css | 1
hosted/skins/default/templates/footer.html | 1
hosted/skins/default/templates/signup.html | 41 --
hosted/skins/default/ui.js | 1
hosted/skins/kolabsys/hosted.css | 26 -
hosted/skins/kolabsys/images/error.png | 1
hosted/skins/kolabsys/images/favicon.png | 1
hosted/skins/kolabsys/images/info.png | 1
hosted/skins/kolabsys/images/loading.gif | 1
hosted/skins/kolabsys/style.css | 1
hosted/skins/kolabsys/templates/signup.html | 20 -
hosted/skins/kolabsys/ui.js | 1
hosted/skins/minimal/hosted.css | 1
hosted/skins/minimal/images/error.png | 1
hosted/skins/minimal/images/favicon.png | 1
hosted/skins/minimal/images/info.png | 1
hosted/skins/minimal/images/loading.gif | 1
hosted/skins/minimal/style.css | 1
hosted/skins/minimal/templates/footer.html | 1
hosted/skins/minimal/templates/signup.html | 23 -
hosted/skins/minimal/ui.js | 1
lib/client/kolab_client_task_signup.php | 327 +++++++++++++++++
lib/functions.php | 1
lib/hosted/kolab_client_task_signup.php | 327 -----------------
lib/hosted/recaptchalib.php | 277 --------------
lib/recaptchalib.php | 277 ++++++++++++++
public_html/index.php | 2
public_html/js/kolab_hosted.js | 120 ++++++
public_html/skins/default/hosted.css | 45 ++
public_html/skins/default/images/logo_kolab.png |binary
public_html/skins/default/templates/signup.html | 32 +
public_html/skins/default/templates/signup_footer.html | 1
public_html/skins/default/ui.js | 2
public_html/skins/kolabsys/hosted.css | 26 +
public_html/skins/kolabsys/style.css | 1
public_html/skins/kolabsys/templates/signup.html | 20 +
public_html/skins/kolabsys/ui.js | 1
public_html/skins/minimal/hosted.css | 1
public_html/skins/minimal/style.css | 1
public_html/skins/minimal/templates/signup.html | 23 +
public_html/skins/minimal/templates/signup_footer.html | 1
public_html/skins/minimal/ui.js | 1
54 files changed, 882 insertions(+), 914 deletions(-)
New commits:
commit 71fe77ab8367cb4473e6bac7d8f002f82a121b99
Author: Aleksander Machniak <alec at alec.pl>
Date: Thu Sep 27 09:25:14 2012 +0200
Integrate hosted/signup with core, fix Smarty cache issue (#1044)
diff --git a/hosted/index.php b/hosted/index.php
index 867a6e1..6414cbe 100644
--- a/hosted/index.php
+++ b/hosted/index.php
@@ -26,16 +26,7 @@
// environment initialization
require_once '../lib/functions.php';
-// starting task
-$task = kolab_utils::get_input('task', kolab_utils::REQUEST_GET);
-
-if (!$task) {
- $task = 'signup';
-}
-
-$class = "kolab_client_task_$task";
-
-$KADM = new $class;
+$KADM = new kolab_client_task_signup;
// run actions and send output
$KADM->run();
diff --git a/hosted/js b/hosted/js
new file mode 120000
index 0000000..050426c
--- /dev/null
+++ b/hosted/js
@@ -0,0 +1 @@
+../public_html/js
\ No newline at end of file
diff --git a/hosted/js/jquery.min.js b/hosted/js/jquery.min.js
deleted file mode 120000
index c3b1873..0000000
--- a/hosted/js/jquery.min.js
+++ /dev/null
@@ -1 +0,0 @@
-../../public_html/js/jquery.min.js
\ No newline at end of file
diff --git a/hosted/js/kolab_admin.js b/hosted/js/kolab_admin.js
deleted file mode 120000
index ea11949..0000000
--- a/hosted/js/kolab_admin.js
+++ /dev/null
@@ -1 +0,0 @@
-../../public_html/js/kolab_admin.js
\ No newline at end of file
diff --git a/hosted/js/kolab_hosted.js b/hosted/js/kolab_hosted.js
deleted file mode 100644
index 9f717ae..0000000
--- a/hosted/js/kolab_hosted.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- +--------------------------------------------------------------------------+
- | This file is part of the Kolab Web Admin Panel |
- | |
- | Copyright (C) 2011-2012, Kolab Systems AG |
- | |
- | This program is free software: you can redistribute it and/or modify |
- | it under the terms of the GNU Affero General Public License as published |
- | by the Free Software Foundation, either version 3 of the License, or |
- | (at your option) any later version. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU Affero General Public License for more details. |
- | |
- | You should have received a copy of the GNU Affero General Public License |
- | along with kadm program. If not, see <http://www.gnu.org/licenses/> |
- +--------------------------------------------------------------------------+
- | Author: Torsten Grote <grote at kolabsys.com> |
- +--------------------------------------------------------------------------+
-*/
-
-// overwrite user_save() function
-kadm.user_save = function(reload, section)
-{
- var data = kadm.serialize_form('#'+this.env.form_id);
-
- // check email address
- if(typeof data.mailalternateaddress != 'undefined' && !isValidEmailAddress(data.mailalternateaddress)) {
- kadm.display_message('signup.wrongmailalternateaddress', 'error');
- kadm.form_value_error('mailalternateaddress');
- return;
- }
-
- if (!kadm.check_required_fields(data)) {
- kadm.display_message('form.required.empty', 'error');
- return;
- }
-
- // check password
- if (data.userpassword != data.userpassword2) {
- kadm.display_message('user.password.mismatch', 'error');
- kadm.form_value_error('userpassword2');
- return;
- }
- delete data['userpassword2'];
-
- kadm.http_post('signup.add_user', {data: data});
-};
-
-kadm.change_user_type = function()
-{
- var data = kadm.serialize_form('#'+this.env.form_id);
-
- kadm.http_post('signup.default', {data: data});
-};
-
-kadm.check_user_availability = function()
-{
- // get form data and build new email address
- var data = kadm.serialize_form('#signup-form');
- var mail = data['uid'] + '@' + data['domain'];
-
- if(isValidEmailAddress(mail)) {
- // update future mail form field
- $('input[name="mail"]').val(mail);
-
- // check if user with that email address already exists
- kadm.http_post('signup.check_user', {data: data});
- } else {
- kadm.update_user_info('signup.wronguid', 'uid');
- }
-};
-
-kadm.update_user_info = function(msg, part)
-{
- var span_id = 'availability';
- if(!part.localeCompare('userpassword')) {
- span_id = 'pass_match';
- }
-
- if (msg) {
- msg = kadm.t(msg);
- }
-
- // display message next to form field
- if($('span[id="'+span_id+'"]').length) {
- // update existing span area
- $('span[id="'+span_id+'"]').html(msg);
- }
- else {
- // add span area and add message
- $('input[name="'+part+'"]').after(' <span id="'+span_id+'" class="form_error">' + msg + '</span>');
- }
-
- // enable/disable button
- if(msg == '') {
- $('input[type="button"]').removeAttr("disabled");
- } else {
- $('input[type="button"]').attr("disabled", "disabled");
- }
-};
-
-
-function password_match()
-{
- if($('input[name="userpassword"]').val().localeCompare($('input[name="userpassword2"]').val())) {
- kadm.update_user_info('user.password.mismatch', 'userpassword');
- }
- else {
- kadm.update_user_info('', 'userpassword');
- }
-}
-
-// TODO use form.validate api call for that
-function isValidEmailAddress(emailAddress) {
- var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
- return pattern.test(emailAddress);
-};
diff --git a/hosted/skins b/hosted/skins
new file mode 120000
index 0000000..5327ffe
--- /dev/null
+++ b/hosted/skins
@@ -0,0 +1 @@
+../public_html/skins
\ No newline at end of file
diff --git a/hosted/skins/default/hosted.css b/hosted/skins/default/hosted.css
deleted file mode 100644
index bba4df6..0000000
--- a/hosted/skins/default/hosted.css
+++ /dev/null
@@ -1,44 +0,0 @@
-body {
- background: #f0f0f0;
- text-align: center;
-}
-
-#bodybox {
- display: inline-block;
- width: 900px;
- text-align: left;
-}
-
-#logo {
- width: 462px;
- height: 100px;
- position: relative;
- margin: 10px;
- cursor: default;
-}
-
-#content {
- padding: 15px;
-}
-
-#taskcontent {
- display: inline-block;
- margin-top: 10px;
- text-align: center;
-}
-
-form#signup-form {
- padding-top: 10px;
-}
-
-td.label {
- vertical-align: top;
-}
-
-table.form td {
- text-align: left;
-}
-
-#footer {
- text-align: center;
-}
diff --git a/hosted/skins/default/images/error.png b/hosted/skins/default/images/error.png
deleted file mode 120000
index fe901a7..0000000
--- a/hosted/skins/default/images/error.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/error.png
\ No newline at end of file
diff --git a/hosted/skins/default/images/favicon.png b/hosted/skins/default/images/favicon.png
deleted file mode 120000
index 7ee1ea8..0000000
--- a/hosted/skins/default/images/favicon.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/favicon.png
\ No newline at end of file
diff --git a/hosted/skins/default/images/info.png b/hosted/skins/default/images/info.png
deleted file mode 120000
index 8e1fec7..0000000
--- a/hosted/skins/default/images/info.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/info.png
\ No newline at end of file
diff --git a/hosted/skins/default/images/loading.gif b/hosted/skins/default/images/loading.gif
deleted file mode 120000
index aaca76f..0000000
--- a/hosted/skins/default/images/loading.gif
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/loading.gif
\ No newline at end of file
diff --git a/hosted/skins/default/images/logo.png b/hosted/skins/default/images/logo.png
deleted file mode 100644
index 0c06ff1..0000000
Binary files a/hosted/skins/default/images/logo.png and /dev/null differ
diff --git a/hosted/skins/default/style.css b/hosted/skins/default/style.css
deleted file mode 120000
index 6f5490d..0000000
--- a/hosted/skins/default/style.css
+++ /dev/null
@@ -1 +0,0 @@
-../../../public_html/skins/default/style.css
\ No newline at end of file
diff --git a/hosted/skins/default/templates/footer.html b/hosted/skins/default/templates/footer.html
deleted file mode 100644
index 24d972d..0000000
--- a/hosted/skins/default/templates/footer.html
+++ /dev/null
@@ -1 +0,0 @@
-{$engine->translate('signup.footer')}
diff --git a/hosted/skins/default/templates/signup.html b/hosted/skins/default/templates/signup.html
deleted file mode 100644
index 8043859..0000000
--- a/hosted/skins/default/templates/signup.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8" />
- <title>{$engine->translate('signup.headline')}</title>
- <link rel="stylesheet" href="{$skin_path}style.css" />
- <link rel="stylesheet" href="{$skin_path}hosted.css" />
- <link rel="shortcut icon" type="image/png" href="{$skin_path}images/favicon.png" />
- <script src="js/jquery.min.js"></script>
- <script src="js/kolab_admin.js"></script>
- <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
- <script src="js/kolab_hosted.js"></script>
- <script src="{$skin_path}ui.js"></script>
-</head>
-<body>
- <div id="bodybox">
- <div id="logo"></div>
- <div id="content">
-
-
- <div id="task_content" class="signup">
-
- <h1>{$engine->translate('signup.headline')}</h1>
-
- <p>{$engine->translate('signup.intro1')}</p>
-
- <p>{$engine->translate('signup.intro2')}</p>
-
- <div id="taskcontent" class="signup">{$form}</div>
-
-
- </div>
-
- </div>
- <div id="footer">
- {include file="footer.html"}
- </div>
- </div>
-{$script}
-</body>
-</html>
diff --git a/hosted/skins/default/ui.js b/hosted/skins/default/ui.js
deleted file mode 120000
index 625253b..0000000
--- a/hosted/skins/default/ui.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../public_html/skins/default/ui.js
\ No newline at end of file
diff --git a/hosted/skins/kolabsys/hosted.css b/hosted/skins/kolabsys/hosted.css
deleted file mode 100644
index 427d57d..0000000
--- a/hosted/skins/kolabsys/hosted.css
+++ /dev/null
@@ -1,26 +0,0 @@
-body {
- background: #F3F3F3;
- text-align: center;
-}
-
-#taskcontent {
- width: 680px;
- min-height: 100px;
- max-height: 460px;
-}
-
-form#signup-form {
- padding-top: 10px;
-}
-
-td.value input {
- width: 250px;
-}
-
-td.label {
- vertical-align: top;
-}
-
-table.form td {
- text-align: left;
-}
diff --git a/hosted/skins/kolabsys/images/error.png b/hosted/skins/kolabsys/images/error.png
deleted file mode 120000
index fe901a7..0000000
--- a/hosted/skins/kolabsys/images/error.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/error.png
\ No newline at end of file
diff --git a/hosted/skins/kolabsys/images/favicon.png b/hosted/skins/kolabsys/images/favicon.png
deleted file mode 120000
index 7ee1ea8..0000000
--- a/hosted/skins/kolabsys/images/favicon.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/favicon.png
\ No newline at end of file
diff --git a/hosted/skins/kolabsys/images/info.png b/hosted/skins/kolabsys/images/info.png
deleted file mode 120000
index 8e1fec7..0000000
--- a/hosted/skins/kolabsys/images/info.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/info.png
\ No newline at end of file
diff --git a/hosted/skins/kolabsys/images/loading.gif b/hosted/skins/kolabsys/images/loading.gif
deleted file mode 120000
index aaca76f..0000000
--- a/hosted/skins/kolabsys/images/loading.gif
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/loading.gif
\ No newline at end of file
diff --git a/hosted/skins/kolabsys/style.css b/hosted/skins/kolabsys/style.css
deleted file mode 120000
index 6f5490d..0000000
--- a/hosted/skins/kolabsys/style.css
+++ /dev/null
@@ -1 +0,0 @@
-../../../public_html/skins/default/style.css
\ No newline at end of file
diff --git a/hosted/skins/kolabsys/templates/signup.html b/hosted/skins/kolabsys/templates/signup.html
deleted file mode 100644
index 7c756ae..0000000
--- a/hosted/skins/kolabsys/templates/signup.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8" />
- <title>Sign Up For Hosted Kolab</title>
- <link rel="stylesheet" href="{$skin_path}style.css" />
- <link rel="stylesheet" href="{$skin_path}hosted.css" />
- <link rel="shortcut icon" type="image/png" href="{$skin_path}images/favicon.png" />
- <script src="js/jquery.min.js"></script>
- <script src="js/kolab_admin.js"></script>
- <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
- <script src="js/kolab_hosted.js"></script>
- <script src="{$skin_path}ui.js"></script>
-</head>
-<body>
- <div id="taskcontent" class="signup">{$form}</div>
-
- {$script}
-</body>
-</html>
diff --git a/hosted/skins/kolabsys/ui.js b/hosted/skins/kolabsys/ui.js
deleted file mode 120000
index 625253b..0000000
--- a/hosted/skins/kolabsys/ui.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../public_html/skins/default/ui.js
\ No newline at end of file
diff --git a/hosted/skins/minimal/hosted.css b/hosted/skins/minimal/hosted.css
deleted file mode 120000
index a66df34..0000000
--- a/hosted/skins/minimal/hosted.css
+++ /dev/null
@@ -1 +0,0 @@
-../default/hosted.css
\ No newline at end of file
diff --git a/hosted/skins/minimal/images/error.png b/hosted/skins/minimal/images/error.png
deleted file mode 120000
index fe901a7..0000000
--- a/hosted/skins/minimal/images/error.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/error.png
\ No newline at end of file
diff --git a/hosted/skins/minimal/images/favicon.png b/hosted/skins/minimal/images/favicon.png
deleted file mode 120000
index 7ee1ea8..0000000
--- a/hosted/skins/minimal/images/favicon.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/favicon.png
\ No newline at end of file
diff --git a/hosted/skins/minimal/images/info.png b/hosted/skins/minimal/images/info.png
deleted file mode 120000
index 8e1fec7..0000000
--- a/hosted/skins/minimal/images/info.png
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/info.png
\ No newline at end of file
diff --git a/hosted/skins/minimal/images/loading.gif b/hosted/skins/minimal/images/loading.gif
deleted file mode 120000
index aaca76f..0000000
--- a/hosted/skins/minimal/images/loading.gif
+++ /dev/null
@@ -1 +0,0 @@
-../../../../public_html/skins/default/images/loading.gif
\ No newline at end of file
diff --git a/hosted/skins/minimal/style.css b/hosted/skins/minimal/style.css
deleted file mode 120000
index 6f5490d..0000000
--- a/hosted/skins/minimal/style.css
+++ /dev/null
@@ -1 +0,0 @@
-../../../public_html/skins/default/style.css
\ No newline at end of file
diff --git a/hosted/skins/minimal/templates/footer.html b/hosted/skins/minimal/templates/footer.html
deleted file mode 100644
index 4b6bac5..0000000
--- a/hosted/skins/minimal/templates/footer.html
+++ /dev/null
@@ -1 +0,0 @@
-This is a service offered by <a href="http://kolabsys.com">Kolab Systems</a>.
diff --git a/hosted/skins/minimal/templates/signup.html b/hosted/skins/minimal/templates/signup.html
deleted file mode 100644
index 961dbf8..0000000
--- a/hosted/skins/minimal/templates/signup.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta charset="utf-8" />
- <title>Sign Up For Hosted Kolab</title>
- <link rel="stylesheet" href="{$skin_path}style.css" />
- <link rel="stylesheet" href="{$skin_path}hosted.css" />
- <link rel="shortcut icon" type="image/png" href="{$skin_path}images/favicon.png" />
- <script src="js/jquery.min.js"></script>
- <script src="js/kolab_admin.js"></script>
- <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
- <script src="js/kolab_hosted.js"></script>
- <script src="{$skin_path}ui.js"></script>
-</head>
-<body>
- <div id="taskcontent" class="signup">{$form}</div>
-
- <div id="footer">
- {include file="footer.html"}
- </div>
-{$script}
-</body>
-</html>
diff --git a/hosted/skins/minimal/ui.js b/hosted/skins/minimal/ui.js
deleted file mode 120000
index 625253b..0000000
--- a/hosted/skins/minimal/ui.js
+++ /dev/null
@@ -1 +0,0 @@
-../../../public_html/skins/default/ui.js
\ No newline at end of file
diff --git a/lib/client/kolab_client_task_signup.php b/lib/client/kolab_client_task_signup.php
new file mode 100644
index 0000000..a320216
--- /dev/null
+++ b/lib/client/kolab_client_task_signup.php
@@ -0,0 +1,327 @@
+<?php
+/*
+ +--------------------------------------------------------------------------+
+ | This file is part of the Kolab Web Admin Panel |
+ | |
+ | Copyright (C) 2011-2012, Kolab Systems AG |
+ | |
+ | This program is free software: you can redistribute it and/or modify |
+ | it under the terms of the GNU Affero General Public License as published |
+ | by the Free Software Foundation, either version 3 of the License, or |
+ | (at your option) any later version. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public License |
+ | along with this program. If not, see <http://www.gnu.org/licenses/> |
+ +--------------------------------------------------------------------------+
+ | Author: Aleksander Machniak <machniak at kolabsys.com> |
+ | Author: Torsten Grote <grote at kolabsys.com> |
+ +--------------------------------------------------------------------------+
+*/
+
+require_once('recaptchalib.php');
+
+class kolab_client_task_signup extends kolab_client_task
+{
+ protected $ajax_only = true;
+
+ /**
+ * Overwrite Main execution.
+ */
+ public function run()
+ {
+ // don't set any cookies
+ ini_set('session.use_cookies', '0');
+
+ // Initialize locales
+ $this->locale_init();
+
+ // Assign self to template variable
+ $this->output->assign('engine', $this);
+
+ // Run security checks
+ // TODO figure out to reenable this
+// $this->input_checks();
+
+ $action = $this->get_input('action', 'GET');
+
+ if ($action) {
+ $method = 'action_' . $action;
+ if (method_exists($this, $method)) {
+ $this->$method();
+ }
+ }
+ else if (method_exists($this, 'action_default')) {
+ $this->action_default();
+ }
+ }
+
+ private function login($domain=NULL)
+ {
+ if(is_null($domain)) {
+ $this->domain = $this->config_get('primary_domain');
+ }
+
+ // Login ($result is a kolab_client_api_result instance)
+ $result = $this->api->login($this->config_get('bind_dn'), $this->config_get('bind_pw'), $this->domain);
+
+ // Set the session token we got in the API client instance, so subsequent
+ // API calls are made in the same session.
+ $this->token = $result->get('session_token');
+ $this->api->set_session_token($this->token);
+ }
+
+ public function action_default()
+ {
+ $this->login();
+
+ $data = $this->get_input('data', 'POST');
+ $form = $this->user_form($data);
+
+ // add captcha
+ $publickey = $this->config_get('recaptcha_public_key');
+
+ if (!empty($publickey)) {
+ // TODO find a less dirty way to add captcha into form
+ $form = preg_replace('/<\/tbody>/', '<tr><td class="label">'.$this->translate('signup.captcha').'</td><td class="value"><div id="recaptcha_div"></div></td></tr></tbody>', $form);
+
+ // load captcha
+ $form .= '
+ <script type="text/javascript">
+ Recaptcha.create("'.$publickey.'", "recaptcha_div", {theme: "red"});
+ </script>';
+ }
+
+ $this->output->assign('form', $form);
+ $this->output->set_object('taskcontent', $form);
+ }
+
+ // check if user already exists
+ public function action_check_user($data = array()) {
+ if(count($data) == 0) $data = $this->get_input('data', 'POST');
+
+ $this->login($data['domain']);
+
+ // Assemble mail attribute
+ $mail = $data['uid'].'@'.$data['domain'];
+
+ $post = array('search' => array('mail' => array('value' => $mail) ) );
+ $result = $this->api->post('users.list', null, $post);
+
+ if($result->get('count') > 0) {
+ $this->output->command('update_user_info("signup.userexists", "uid")');
+ return false;
+ }
+
+ $this->output->command('update_user_info("", "uid")');
+ return true;
+ }
+
+ public function action_add_user() {
+ $data = $this->get_input('data', 'POST');
+
+ $private_key = $this->config_get('recaptcha_private_key');
+
+ if (!empty($private_key)) {
+ // Check for valid CAPTCHA
+ $resp = recaptcha_check_answer(
+ $private_key,
+ $_SERVER['REMOTE_ADDR'],
+ $data['recaptcha_challenge_field'],
+ $data['recaptcha_response_field']
+ );
+
+ if (!$resp->is_valid) {
+ // What happens when the CAPTCHA was entered incorrectly
+ $this->output->command('display_message', "The reCAPTCHA wasn't entered correctly. Please reload and try it again.", 'error');
+ return;
+ }
+
+ }
+
+ // Check again for user availability before adding user
+ // this also logs into the API
+ // TODO perform security check on value of $data['uid'] and $data['domain']
+ if(!$this->action_check_user($data)) {
+ $this->output->command('form_value_error', 'uid');
+ return;
+ }
+
+ $this->api->get('system.select_domain', array('domain', $data['domain']));
+
+ // Remove domain from $data before adding user
+ unset($data['domain']);
+
+ $data['cn'] = $this->api->post('form_value.generate', $data);
+
+ // Add user
+ $result = $this->api->post('user.add', null, $data);
+
+ if (array_key_exists('error_code', $result)) {
+ $this->output->command('display_message', 'internalerror', 'error');
+ return;
+ } else {
+ $this->output->set_object('taskcontent', 'signup.usercreated');
+ }
+ }
+
+ private function user_form($data = array()) {
+ $attribs['id'] = 'signup-form';
+
+ $fields_map = array(
+ 'type_id' => 'other',
+ 'givenname' => 'other',
+ 'sn' => 'other',
+ 'cn' => 'other',
+ 'mailalternateaddress' => 'other',
+ 'uid' => 'other',
+ 'domain' => 'other',
+ 'userpassword' => 'other',
+ 'userpassword2' => 'other',
+ 'mail' => 'other',
+ 'alias' => 'other',
+ );
+
+ // Prepare fields
+ list($fields, $types, $type) = $this->form_prepare('user', $data, array('userpassword2'), 'hosted');
+
+ // Show only required fields
+ foreach ($fields as $field_name => $field_attrs) {
+ if(!array_key_exists('required', $field_attrs) or $field_attrs['required'] != 'true') {
+ unset($fields[$field_name]);
+ }
+ }
+
+ // Add user type id selector
+ $accttypes = array();
+ foreach ($types as $idx => $elem) {
+ if($elem['used_for'] == 'hosted') {
+ $accttypes[$idx] = array('value' => $idx, 'content' => $elem['name']);
+ }
+ }
+
+ $fields['type_id'] = array(
+ 'section' => 'personal',
+ 'type' => kolab_form::INPUT_SELECT,
+ 'options' => $accttypes,
+ 'onchange' => "kadm.change_user_type()",
+ );
+
+ // Add object type field
+ $fields['object_type'] = array(
+ 'type' => kolab_form::INPUT_HIDDEN,
+ 'value' => 'user',
+ );
+
+ // Add available domains
+ $fields['domain'] = array(
+ 'type' => kolab_form::INPUT_SELECT,
+ 'options' => $this->get_domains(),
+ 'onchange' => 'kadm.check_user_availability()',
+ );
+
+ // Check for user availability
+ $fields['uid']['onchange'] = 'kadm.check_user_availability()';
+
+ // Hide cn field
+ if (isset($fields['cn'])) {
+ // TODO use type info from user types table
+ $fields['cn']['type'] = kolab_form::INPUT_HIDDEN;
+
+ // TODO auto generate value again with indirect API call
+ $fields['cn']['value'] = 'temporary fake cn';
+ $fields['sn']['onchange'] = '';
+ $fields['givenname']['onchange'] = '';
+ }
+
+ // Add password confirmation
+ if (isset($fields['userpassword'])) {
+ $fields['userpassword2'] = $fields['userpassword'];
+ $fields['userpassword2']['onchange'] = 'password_match()';
+ }
+
+ // Change field labels for hosted case
+ $fields['uid']['label'] = 'signup.username';
+ $fields['mail']['label'] = 'signup.futuremail';
+ if(isset($fields['mailalternateaddress'])) $fields['mailalternateaddress']['label'] = 'signup.mailalternateaddress';
+ $fields['domain']['label'] = 'signup.domain';
+
+ // Create form object and populate with fields
+ $form = $this->form_create('user', $attribs, array('other'), $fields, $fields_map, $data, true);
+
+ $form->set_title($this->translate('signup.formtitle'));
+
+ $this->output->add_translation('user.password.mismatch', 'user.add.success', 'signup.wronguid');
+
+ return $form->output();
+ }
+
+ protected function get_domains() {
+ // Get a list of domains ($domains again is a kolab_client_api_result instance)
+ $domains_list = $this->api->get('domains.list')->get('list');
+
+ if (empty($domains_list)) {
+ return array();
+ }
+
+ // The domain name attribute (the name of the LDAP attribute that holds the actual domain name space)
+ // is configurable as well. Provide a fallback.
+ $domain_name_attribute = $this->config->get('ldap','domain_name_attribute');
+ if (empty($domain_name_attribute)) {
+ $domain_name_attribute = 'associateddomain';
+ }
+
+ // Placeholder for the domain names in this deployment
+ $domain_names = array();
+
+ foreach ($domains_list as $domain_dn => $domain_attrs) {
+ // If $domain_attrs[$domain_name_attribute] is an array, the primary domain name space
+ // is the first value in the array.
+ if (is_array($domain_attrs[$domain_name_attribute])) {
+ $_domain_names = $domain_attrs[$domain_name_attribute];
+ $domain_name = array_shift($domain_attrs[$domain_name_attribute]);
+ } else {
+ $_domain_names = (array)($domain_attrs[$domain_name_attribute]);
+ $domain_name = $domain_attrs[$domain_name_attribute];
+ }
+
+ $parent_domain_only = $this->config->get($domain_name, 'hosted_parent_domain_only');
+
+ if (!empty($parent_domain_only) && in_array(strtolower($parent_domain_only), array('1', 'yes', 'true'))) {
+ $domain_names = array_merge($domain_names, array($domain_name));
+ } else {
+ $domain_names = array_merge($domain_names, $_domain_names);
+ }
+ }
+
+ // prepare array with proper key ids for form building
+ foreach ($domain_names as $domain) {
+ $domain_form_names[$domain] = $domain;
+ }
+
+ return $domain_form_names;
+ }
+
+ /**
+ * Overrides config_get() from kolab_client_task
+ * Returns configuration option value for hosting.
+ *
+ * @param string $name Option name
+ * @param mixed $fallback Default value
+ * @param int $type Value type (one of Conf class constants)
+ *
+ * @return mixed Option value
+ */
+ public function config_get($name, $fallback = null, $type = null)
+ {
+ $value = $this->config->get('kolab_hosting', $name, $type);
+ if($value === null) {
+ $value = parent::config_get($name, $fallback, $type);
+ }
+ return $value !== null ? $value : $fallback;
+ }
+}
diff --git a/lib/functions.php b/lib/functions.php
index 8c74cf7..9761358 100644
--- a/lib/functions.php
+++ b/lib/functions.php
@@ -47,7 +47,6 @@ $include_path = INSTALL_PATH . PATH_SEPARATOR;
$include_path .= INSTALL_PATH . '/client' . PATH_SEPARATOR;
$include_path .= INSTALL_PATH . '/api' . PATH_SEPARATOR;
$include_path .= INSTALL_PATH . '/ext' . PATH_SEPARATOR;
-$include_path .= INSTALL_PATH . '/hosted' . PATH_SEPARATOR;
$include_path .= ini_get('include_path');
if (set_include_path($include_path) === false) {
diff --git a/lib/hosted/kolab_client_task_signup.php b/lib/hosted/kolab_client_task_signup.php
deleted file mode 100644
index 6ebcdd9..0000000
--- a/lib/hosted/kolab_client_task_signup.php
+++ /dev/null
@@ -1,327 +0,0 @@
-<?php
-/*
- +--------------------------------------------------------------------------+
- | This file is part of the Kolab Web Admin Panel |
- | |
- | Copyright (C) 2011-2012, Kolab Systems AG |
- | |
- | This program is free software: you can redistribute it and/or modify |
- | it under the terms of the GNU Affero General Public License as published |
- | by the Free Software Foundation, either version 3 of the License, or |
- | (at your option) any later version. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU Affero General Public License for more details. |
- | |
- | You should have received a copy of the GNU Affero General Public License |
- | along with this program. If not, see <http://www.gnu.org/licenses/> |
- +--------------------------------------------------------------------------+
- | Author: Aleksander Machniak <machniak at kolabsys.com> |
- | Author: Torsten Grote <grote at kolabsys.com> |
- +--------------------------------------------------------------------------+
-*/
-
-require_once('hosted/recaptchalib.php');
-
-class kolab_client_task_signup extends kolab_client_task
-{
- protected $ajax_only = true;
-
- /**
- * Overwrite Main execution.
- */
- public function run()
- {
- // don't set any cookies
- ini_set('session.use_cookies', '0');
-
- // Initialize locales
- $this->locale_init();
-
- // Assign self to template variable
- $this->output->assign('engine', $this);
-
- // Run security checks
- // TODO figure out to reenable this
-// $this->input_checks();
-
- $action = $this->get_input('action', 'GET');
-
- if ($action) {
- $method = 'action_' . $action;
- if (method_exists($this, $method)) {
- $this->$method();
- }
- }
- else if (method_exists($this, 'action_default')) {
- $this->action_default();
- }
- }
-
- private function login($domain=NULL)
- {
- if(is_null($domain)) {
- $this->domain = $this->config_get('primary_domain');
- }
-
- // Login ($result is a kolab_client_api_result instance)
- $result = $this->api->login($this->config_get('bind_dn'), $this->config_get('bind_pw'), $this->domain);
-
- // Set the session token we got in the API client instance, so subsequent
- // API calls are made in the same session.
- $this->token = $result->get('session_token');
- $this->api->set_session_token($this->token);
- }
-
- public function action_default()
- {
- $this->login();
-
- $data = $this->get_input('data', 'POST');
- $form = $this->user_form($data);
-
- // add captcha
- $publickey = $this->config_get('recaptcha_public_key');
-
- if (!empty($publickey)) {
- // TODO find a less dirty way to add captcha into form
- $form = preg_replace('/<\/tbody>/', '<tr><td class="label">'.$this->translate('signup.captcha').'</td><td class="value"><div id="recaptcha_div"></div></td></tr></tbody>', $form);
-
- // load captcha
- $form .= '
- <script type="text/javascript">
- Recaptcha.create("'.$publickey.'", "recaptcha_div", {theme: "red"});
- </script>';
- }
-
- $this->output->assign('form', $form);
- $this->output->set_object('taskcontent', $form);
- }
-
- // check if user already exists
- public function action_check_user($data = array()) {
- if(count($data) == 0) $data = $this->get_input('data', 'POST');
-
- $this->login($data['domain']);
-
- // Assemble mail attribute
- $mail = $data['uid'].'@'.$data['domain'];
-
- $post = array('search' => array('mail' => array('value' => $mail) ) );
- $result = $this->api->post('users.list', null, $post);
-
- if($result->get('count') > 0) {
- $this->output->command('update_user_info("signup.userexists", "uid")');
- return false;
- }
-
- $this->output->command('update_user_info("", "uid")');
- return true;
- }
-
- public function action_add_user() {
- $data = $this->get_input('data', 'POST');
-
- $private_key = $this->config_get('recaptcha_private_key');
-
- if (!empty($private_key)) {
- // Check for valid CAPTCHA
- $resp = recaptcha_check_answer(
- $private_key,
- $_SERVER['REMOTE_ADDR'],
- $data['recaptcha_challenge_field'],
- $data['recaptcha_response_field']
- );
-
- if (!$resp->is_valid) {
- // What happens when the CAPTCHA was entered incorrectly
- $this->output->command('display_message', "The reCAPTCHA wasn't entered correctly. Please reload and try it again.", 'error');
- return;
- }
-
- }
-
- // Check again for user availability before adding user
- // this also logs into the API
- // TODO perform security check on value of $data['uid'] and $data['domain']
- if(!$this->action_check_user($data)) {
- $this->output->command('form_value_error', 'uid');
- return;
- }
-
- $this->api->get('system.select_domain', array('domain', $data['domain']));
-
- // Remove domain from $data before adding user
- unset($data['domain']);
-
- $data['cn'] = $this->api->post('form_value.generate', $data);
-
- // Add user
- $result = $this->api->post('user.add', null, $data);
-
- if (array_key_exists('error_code', $result)) {
- $this->output->command('display_message', 'internalerror', 'error');
- return;
- } else {
- $this->output->set_object('taskcontent', 'signup.usercreated');
- }
- }
-
- private function user_form($data = array()) {
- $attribs['id'] = 'signup-form';
-
- $fields_map = array(
- 'type_id' => 'other',
- 'givenname' => 'other',
- 'sn' => 'other',
- 'cn' => 'other',
- 'mailalternateaddress' => 'other',
- 'uid' => 'other',
- 'domain' => 'other',
- 'userpassword' => 'other',
- 'userpassword2' => 'other',
- 'mail' => 'other',
- 'alias' => 'other',
- );
-
- // Prepare fields
- list($fields, $types, $type) = $this->form_prepare('user', $data, array('userpassword2'), 'hosted');
-
- // Show only required fields
- foreach ($fields as $field_name => $field_attrs) {
- if(!array_key_exists('required', $field_attrs) or $field_attrs['required'] != 'true') {
- unset($fields[$field_name]);
- }
- }
-
- // Add user type id selector
- $accttypes = array();
- foreach ($types as $idx => $elem) {
- if($elem['used_for'] == 'hosted') {
- $accttypes[$idx] = array('value' => $idx, 'content' => $elem['name']);
- }
- }
-
- $fields['type_id'] = array(
- 'section' => 'personal',
- 'type' => kolab_form::INPUT_SELECT,
- 'options' => $accttypes,
- 'onchange' => "kadm.change_user_type()",
- );
-
- // Add object type field
- $fields['object_type'] = array(
- 'type' => kolab_form::INPUT_HIDDEN,
- 'value' => 'user',
- );
-
- // Add available domains
- $fields['domain'] = array(
- 'type' => kolab_form::INPUT_SELECT,
- 'options' => $this->get_domains(),
- 'onchange' => 'kadm.check_user_availability()',
- );
-
- // Check for user availability
- $fields['uid']['onchange'] = 'kadm.check_user_availability()';
-
- // Hide cn field
- if (isset($fields['cn'])) {
- // TODO use type info from user types table
- $fields['cn']['type'] = kolab_form::INPUT_HIDDEN;
-
- // TODO auto generate value again with indirect API call
- $fields['cn']['value'] = 'temporary fake cn';
- $fields['sn']['onchange'] = '';
- $fields['givenname']['onchange'] = '';
- }
-
- // Add password confirmation
- if (isset($fields['userpassword'])) {
- $fields['userpassword2'] = $fields['userpassword'];
- $fields['userpassword2']['onchange'] = 'password_match()';
- }
-
- // Change field labels for hosted case
- $fields['uid']['label'] = 'signup.username';
- $fields['mail']['label'] = 'signup.futuremail';
- if(isset($fields['mailalternateaddress'])) $fields['mailalternateaddress']['label'] = 'signup.mailalternateaddress';
- $fields['domain']['label'] = 'signup.domain';
-
- // Create form object and populate with fields
- $form = $this->form_create('user', $attribs, array('other'), $fields, $fields_map, $data, true);
-
- $form->set_title($this->translate('signup.formtitle'));
-
- $this->output->add_translation('user.password.mismatch', 'user.add.success', 'signup.wronguid');
-
- return $form->output();
- }
-
- protected function get_domains() {
- // Get a list of domains ($domains again is a kolab_client_api_result instance)
- $domains_list = $this->api->get('domains.list')->get('list');
-
- if (empty($domains_list)) {
- return array();
- }
-
- // The domain name attribute (the name of the LDAP attribute that holds the actual domain name space)
- // is configurable as well. Provide a fallback.
- $domain_name_attribute = $this->config->get('ldap','domain_name_attribute');
- if (empty($domain_name_attribute)) {
- $domain_name_attribute = 'associateddomain';
- }
-
- // Placeholder for the domain names in this deployment
- $domain_names = array();
-
- foreach ($domains_list as $domain_dn => $domain_attrs) {
- // If $domain_attrs[$domain_name_attribute] is an array, the primary domain name space
- // is the first value in the array.
- if (is_array($domain_attrs[$domain_name_attribute])) {
- $_domain_names = $domain_attrs[$domain_name_attribute];
- $domain_name = array_shift($domain_attrs[$domain_name_attribute]);
- } else {
- $_domain_names = (array)($domain_attrs[$domain_name_attribute]);
- $domain_name = $domain_attrs[$domain_name_attribute];
- }
-
- $parent_domain_only = $this->config->get($domain_name, 'hosted_parent_domain_only');
-
- if (!empty($parent_domain_only) && in_array(strtolower($parent_domain_only), array('1', 'yes', 'true'))) {
- $domain_names = array_merge($domain_names, array($domain_name));
- } else {
- $domain_names = array_merge($domain_names, $_domain_names);
- }
- }
-
- // prepare array with proper key ids for form building
- foreach ($domain_names as $domain) {
- $domain_form_names[$domain] = $domain;
- }
-
- return $domain_form_names;
- }
-
- /**
- * Overrides config_get() from kolab_client_task
- * Returns configuration option value for hosting.
- *
- * @param string $name Option name
- * @param mixed $fallback Default value
- * @param int $type Value type (one of Conf class constants)
- *
- * @return mixed Option value
- */
- public function config_get($name, $fallback = null, $type = null)
- {
- $value = $this->config->get('kolab_hosting', $name, $type);
- if($value === null) {
- $value = parent::config_get($name, $fallback, $type);
- }
- return $value !== null ? $value : $fallback;
- }
-}
diff --git a/lib/hosted/recaptchalib.php b/lib/hosted/recaptchalib.php
deleted file mode 100644
index 32c4f4d..0000000
--- a/lib/hosted/recaptchalib.php
+++ /dev/null
@@ -1,277 +0,0 @@
-<?php
-/*
- * This is a PHP library that handles calling reCAPTCHA.
- * - Documentation and latest version
- * http://recaptcha.net/plugins/php/
- * - Get a reCAPTCHA API Key
- * https://www.google.com/recaptcha/admin/create
- * - Discussion group
- * http://groups.google.com/group/recaptcha
- *
- * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
- * AUTHORS:
- * Mike Crawford
- * Ben Maurer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- * The reCAPTCHA server URL's
- */
-define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
-define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");
-define("RECAPTCHA_VERIFY_SERVER", "www.google.com");
-
-/**
- * Encodes the given data into a query string format
- * @param $data - array of string elements to be encoded
- * @return string - encoded request
- */
-function _recaptcha_qsencode ($data) {
- $req = "";
- foreach ( $data as $key => $value )
- $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
-
- // Cut the last '&'
- $req=substr($req,0,strlen($req)-1);
- return $req;
-}
-
-
-
-/**
- * Submits an HTTP POST to a reCAPTCHA server
- * @param string $host
- * @param string $path
- * @param array $data
- * @param int port
- * @return array response
- */
-function _recaptcha_http_post($host, $path, $data, $port = 80) {
-
- $req = _recaptcha_qsencode ($data);
-
- $http_request = "POST $path HTTP/1.0\r\n";
- $http_request .= "Host: $host\r\n";
- $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
- $http_request .= "Content-Length: " . strlen($req) . "\r\n";
- $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
- $http_request .= "\r\n";
- $http_request .= $req;
-
- $response = '';
- if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
- die ('Could not open socket');
- }
-
- fwrite($fs, $http_request);
-
- while ( !feof($fs) )
- $response .= fgets($fs, 1160); // One TCP-IP packet
- fclose($fs);
- $response = explode("\r\n\r\n", $response, 2);
-
- return $response;
-}
-
-
-
-/**
- * Gets the challenge HTML (javascript and non-javascript version).
- * This is called from the browser, and the resulting reCAPTCHA HTML widget
- * is embedded within the HTML form it was called from.
- * @param string $pubkey A public key for reCAPTCHA
- * @param string $error The error given by reCAPTCHA (optional, default is null)
- * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
-
- * @return string - The HTML to be embedded in the user's form.
- */
-function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
-{
- if ($pubkey == null || $pubkey == '') {
- die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
- }
-
- if ($use_ssl) {
- $server = RECAPTCHA_API_SECURE_SERVER;
- } else {
- $server = RECAPTCHA_API_SERVER;
- }
-
- $errorpart = "";
- if ($error) {
- $errorpart = "&error=" . $error;
- }
- return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
-
- <noscript>
- <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
- <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
- <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
- </noscript>';
-}
-
-
-
-
-/**
- * A ReCaptchaResponse is returned from recaptcha_check_answer()
- */
-class ReCaptchaResponse {
- var $is_valid;
- var $error;
-}
-
-
-/**
- * Calls an HTTP POST function to verify if the user's guess was correct
- * @param string $privkey
- * @param string $remoteip
- * @param string $challenge
- * @param string $response
- * @param array $extra_params an array of extra variables to post to the server
- * @return ReCaptchaResponse
- */
-function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
-{
- if ($privkey == null || $privkey == '') {
- die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
- }
-
- if ($remoteip == null || $remoteip == '') {
- die ("For security reasons, you must pass the remote ip to reCAPTCHA");
- }
-
-
-
- //discard spam submissions
- if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
- $recaptcha_response = new ReCaptchaResponse();
- $recaptcha_response->is_valid = false;
- $recaptcha_response->error = 'incorrect-captcha-sol';
- return $recaptcha_response;
- }
-
- $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
- array (
- 'privatekey' => $privkey,
- 'remoteip' => $remoteip,
- 'challenge' => $challenge,
- 'response' => $response
- ) + $extra_params
- );
-
- $answers = explode ("\n", $response [1]);
- $recaptcha_response = new ReCaptchaResponse();
-
- if (trim ($answers [0]) == 'true') {
- $recaptcha_response->is_valid = true;
- }
- else {
- $recaptcha_response->is_valid = false;
- $recaptcha_response->error = $answers [1];
- }
- return $recaptcha_response;
-
-}
-
-/**
- * gets a URL where the user can sign up for reCAPTCHA. If your application
- * has a configuration page where you enter a key, you should provide a link
- * using this function.
- * @param string $domain The domain where the page is hosted
- * @param string $appname The name of your application
- */
-function recaptcha_get_signup_url ($domain = null, $appname = null) {
- return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
-}
-
-function _recaptcha_aes_pad($val) {
- $block_size = 16;
- $numpad = $block_size - (strlen ($val) % $block_size);
- return str_pad($val, strlen ($val) + $numpad, chr($numpad));
-}
-
-/* Mailhide related code */
-
-function _recaptcha_aes_encrypt($val,$ky) {
- if (! function_exists ("mcrypt_encrypt")) {
- die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
- }
- $mode=MCRYPT_MODE_CBC;
- $enc=MCRYPT_RIJNDAEL_128;
- $val=_recaptcha_aes_pad($val);
- return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
-}
-
-
-function _recaptcha_mailhide_urlbase64 ($x) {
- return strtr(base64_encode ($x), '+/', '-_');
-}
-
-/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
-function recaptcha_mailhide_url($pubkey, $privkey, $email) {
- if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
- die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
- "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
- }
-
-
- $ky = pack('H*', $privkey);
- $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
-
- return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
-}
-
-/**
- * gets the parts of the email to expose to the user.
- * eg, given johndoe at example,com return ["john", "example.com"].
- * the email is then displayed as john... at example.com
- */
-function _recaptcha_mailhide_email_parts ($email) {
- $arr = preg_split("/@/", $email );
-
- if (strlen ($arr[0]) <= 4) {
- $arr[0] = substr ($arr[0], 0, 1);
- } else if (strlen ($arr[0]) <= 6) {
- $arr[0] = substr ($arr[0], 0, 3);
- } else {
- $arr[0] = substr ($arr[0], 0, 4);
- }
- return $arr;
-}
-
-/**
- * Gets html to display an email address given a public an private key.
- * to get a key, go to:
- *
- * http://www.google.com/recaptcha/mailhide/apikey
- */
-function recaptcha_mailhide_html($pubkey, $privkey, $email) {
- $emailparts = _recaptcha_mailhide_email_parts ($email);
- $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
-
- return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
- "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
-
-}
-
-
-?>
diff --git a/lib/recaptchalib.php b/lib/recaptchalib.php
new file mode 100644
index 0000000..32c4f4d
--- /dev/null
+++ b/lib/recaptchalib.php
@@ -0,0 +1,277 @@
+<?php
+/*
+ * This is a PHP library that handles calling reCAPTCHA.
+ * - Documentation and latest version
+ * http://recaptcha.net/plugins/php/
+ * - Get a reCAPTCHA API Key
+ * https://www.google.com/recaptcha/admin/create
+ * - Discussion group
+ * http://groups.google.com/group/recaptcha
+ *
+ * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
+ * AUTHORS:
+ * Mike Crawford
+ * Ben Maurer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * The reCAPTCHA server URL's
+ */
+define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
+define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");
+define("RECAPTCHA_VERIFY_SERVER", "www.google.com");
+
+/**
+ * Encodes the given data into a query string format
+ * @param $data - array of string elements to be encoded
+ * @return string - encoded request
+ */
+function _recaptcha_qsencode ($data) {
+ $req = "";
+ foreach ( $data as $key => $value )
+ $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
+
+ // Cut the last '&'
+ $req=substr($req,0,strlen($req)-1);
+ return $req;
+}
+
+
+
+/**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+function _recaptcha_http_post($host, $path, $data, $port = 80) {
+
+ $req = _recaptcha_qsencode ($data);
+
+ $http_request = "POST $path HTTP/1.0\r\n";
+ $http_request .= "Host: $host\r\n";
+ $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+ $http_request .= "Content-Length: " . strlen($req) . "\r\n";
+ $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+ $http_request .= "\r\n";
+ $http_request .= $req;
+
+ $response = '';
+ if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
+ die ('Could not open socket');
+ }
+
+ fwrite($fs, $http_request);
+
+ while ( !feof($fs) )
+ $response .= fgets($fs, 1160); // One TCP-IP packet
+ fclose($fs);
+ $response = explode("\r\n\r\n", $response, 2);
+
+ return $response;
+}
+
+
+
+/**
+ * Gets the challenge HTML (javascript and non-javascript version).
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget
+ * is embedded within the HTML form it was called from.
+ * @param string $pubkey A public key for reCAPTCHA
+ * @param string $error The error given by reCAPTCHA (optional, default is null)
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
+
+ * @return string - The HTML to be embedded in the user's form.
+ */
+function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
+{
+ if ($pubkey == null || $pubkey == '') {
+ die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
+ }
+
+ if ($use_ssl) {
+ $server = RECAPTCHA_API_SECURE_SERVER;
+ } else {
+ $server = RECAPTCHA_API_SERVER;
+ }
+
+ $errorpart = "";
+ if ($error) {
+ $errorpart = "&error=" . $error;
+ }
+ return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
+
+ <noscript>
+ <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
+ <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+ <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
+ </noscript>';
+}
+
+
+
+
+/**
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()
+ */
+class ReCaptchaResponse {
+ var $is_valid;
+ var $error;
+}
+
+
+/**
+ * Calls an HTTP POST function to verify if the user's guess was correct
+ * @param string $privkey
+ * @param string $remoteip
+ * @param string $challenge
+ * @param string $response
+ * @param array $extra_params an array of extra variables to post to the server
+ * @return ReCaptchaResponse
+ */
+function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
+{
+ if ($privkey == null || $privkey == '') {
+ die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
+ }
+
+ if ($remoteip == null || $remoteip == '') {
+ die ("For security reasons, you must pass the remote ip to reCAPTCHA");
+ }
+
+
+
+ //discard spam submissions
+ if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
+ $recaptcha_response = new ReCaptchaResponse();
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = 'incorrect-captcha-sol';
+ return $recaptcha_response;
+ }
+
+ $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
+ array (
+ 'privatekey' => $privkey,
+ 'remoteip' => $remoteip,
+ 'challenge' => $challenge,
+ 'response' => $response
+ ) + $extra_params
+ );
+
+ $answers = explode ("\n", $response [1]);
+ $recaptcha_response = new ReCaptchaResponse();
+
+ if (trim ($answers [0]) == 'true') {
+ $recaptcha_response->is_valid = true;
+ }
+ else {
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = $answers [1];
+ }
+ return $recaptcha_response;
+
+}
+
+/**
+ * gets a URL where the user can sign up for reCAPTCHA. If your application
+ * has a configuration page where you enter a key, you should provide a link
+ * using this function.
+ * @param string $domain The domain where the page is hosted
+ * @param string $appname The name of your application
+ */
+function recaptcha_get_signup_url ($domain = null, $appname = null) {
+ return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
+}
+
+function _recaptcha_aes_pad($val) {
+ $block_size = 16;
+ $numpad = $block_size - (strlen ($val) % $block_size);
+ return str_pad($val, strlen ($val) + $numpad, chr($numpad));
+}
+
+/* Mailhide related code */
+
+function _recaptcha_aes_encrypt($val,$ky) {
+ if (! function_exists ("mcrypt_encrypt")) {
+ die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
+ }
+ $mode=MCRYPT_MODE_CBC;
+ $enc=MCRYPT_RIJNDAEL_128;
+ $val=_recaptcha_aes_pad($val);
+ return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+
+function _recaptcha_mailhide_urlbase64 ($x) {
+ return strtr(base64_encode ($x), '+/', '-_');
+}
+
+/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
+function recaptcha_mailhide_url($pubkey, $privkey, $email) {
+ if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
+ die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
+ "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
+ }
+
+
+ $ky = pack('H*', $privkey);
+ $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
+
+ return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
+}
+
+/**
+ * gets the parts of the email to expose to the user.
+ * eg, given johndoe at example,com return ["john", "example.com"].
+ * the email is then displayed as john... at example.com
+ */
+function _recaptcha_mailhide_email_parts ($email) {
+ $arr = preg_split("/@/", $email );
+
+ if (strlen ($arr[0]) <= 4) {
+ $arr[0] = substr ($arr[0], 0, 1);
+ } else if (strlen ($arr[0]) <= 6) {
+ $arr[0] = substr ($arr[0], 0, 3);
+ } else {
+ $arr[0] = substr ($arr[0], 0, 4);
+ }
+ return $arr;
+}
+
+/**
+ * Gets html to display an email address given a public an private key.
+ * to get a key, go to:
+ *
+ * http://www.google.com/recaptcha/mailhide/apikey
+ */
+function recaptcha_mailhide_html($pubkey, $privkey, $email) {
+ $emailparts = _recaptcha_mailhide_email_parts ($email);
+ $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
+
+ return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
+ "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
+
+}
+
+
+?>
diff --git a/public_html/index.php b/public_html/index.php
index 3e78361..1f9f1ed 100644
--- a/public_html/index.php
+++ b/public_html/index.php
@@ -29,7 +29,7 @@ require_once '../lib/functions.php';
// starting task
$task = kolab_utils::get_input('task', kolab_utils::REQUEST_GET);
-if (!$task) {
+if (!$task || $task == 'signup') {
$task = 'main';
}
diff --git a/public_html/js/kolab_hosted.js b/public_html/js/kolab_hosted.js
new file mode 100644
index 0000000..9f717ae
--- /dev/null
+++ b/public_html/js/kolab_hosted.js
@@ -0,0 +1,120 @@
+/*
+ +--------------------------------------------------------------------------+
+ | This file is part of the Kolab Web Admin Panel |
+ | |
+ | Copyright (C) 2011-2012, Kolab Systems AG |
+ | |
+ | This program is free software: you can redistribute it and/or modify |
+ | it under the terms of the GNU Affero General Public License as published |
+ | by the Free Software Foundation, either version 3 of the License, or |
+ | (at your option) any later version. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public License |
+ | along with kadm program. If not, see <http://www.gnu.org/licenses/> |
+ +--------------------------------------------------------------------------+
+ | Author: Torsten Grote <grote at kolabsys.com> |
+ +--------------------------------------------------------------------------+
+*/
+
+// overwrite user_save() function
+kadm.user_save = function(reload, section)
+{
+ var data = kadm.serialize_form('#'+this.env.form_id);
+
+ // check email address
+ if(typeof data.mailalternateaddress != 'undefined' && !isValidEmailAddress(data.mailalternateaddress)) {
+ kadm.display_message('signup.wrongmailalternateaddress', 'error');
+ kadm.form_value_error('mailalternateaddress');
+ return;
+ }
+
+ if (!kadm.check_required_fields(data)) {
+ kadm.display_message('form.required.empty', 'error');
+ return;
+ }
+
+ // check password
+ if (data.userpassword != data.userpassword2) {
+ kadm.display_message('user.password.mismatch', 'error');
+ kadm.form_value_error('userpassword2');
+ return;
+ }
+ delete data['userpassword2'];
+
+ kadm.http_post('signup.add_user', {data: data});
+};
+
+kadm.change_user_type = function()
+{
+ var data = kadm.serialize_form('#'+this.env.form_id);
+
+ kadm.http_post('signup.default', {data: data});
+};
+
+kadm.check_user_availability = function()
+{
+ // get form data and build new email address
+ var data = kadm.serialize_form('#signup-form');
+ var mail = data['uid'] + '@' + data['domain'];
+
+ if(isValidEmailAddress(mail)) {
+ // update future mail form field
+ $('input[name="mail"]').val(mail);
+
+ // check if user with that email address already exists
+ kadm.http_post('signup.check_user', {data: data});
+ } else {
+ kadm.update_user_info('signup.wronguid', 'uid');
+ }
+};
+
+kadm.update_user_info = function(msg, part)
+{
+ var span_id = 'availability';
+ if(!part.localeCompare('userpassword')) {
+ span_id = 'pass_match';
+ }
+
+ if (msg) {
+ msg = kadm.t(msg);
+ }
+
+ // display message next to form field
+ if($('span[id="'+span_id+'"]').length) {
+ // update existing span area
+ $('span[id="'+span_id+'"]').html(msg);
+ }
+ else {
+ // add span area and add message
+ $('input[name="'+part+'"]').after(' <span id="'+span_id+'" class="form_error">' + msg + '</span>');
+ }
+
+ // enable/disable button
+ if(msg == '') {
+ $('input[type="button"]').removeAttr("disabled");
+ } else {
+ $('input[type="button"]').attr("disabled", "disabled");
+ }
+};
+
+
+function password_match()
+{
+ if($('input[name="userpassword"]').val().localeCompare($('input[name="userpassword2"]').val())) {
+ kadm.update_user_info('user.password.mismatch', 'userpassword');
+ }
+ else {
+ kadm.update_user_info('', 'userpassword');
+ }
+}
+
+// TODO use form.validate api call for that
+function isValidEmailAddress(emailAddress) {
+ var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
+ return pattern.test(emailAddress);
+};
diff --git a/public_html/skins/default/hosted.css b/public_html/skins/default/hosted.css
new file mode 100644
index 0000000..694d19d
--- /dev/null
+++ b/public_html/skins/default/hosted.css
@@ -0,0 +1,45 @@
+body {
+ background: #f0f0f0;
+ text-align: center;
+}
+
+#bodybox {
+ display: inline-block;
+ width: 900px;
+ text-align: left;
+}
+
+#logo {
+ width: 462px;
+ height: 100px;
+ position: relative;
+ margin: 10px;
+ cursor: default;
+ background: url(images/logo_kolab.png) 0 0 no-repeat;
+}
+
+#content {
+ padding: 15px;
+}
+
+#taskcontent {
+ display: inline-block;
+ margin-top: 10px;
+ text-align: center;
+}
+
+form#signup-form {
+ padding-top: 10px;
+}
+
+td.label {
+ vertical-align: top;
+}
+
+table.form td {
+ text-align: left;
+}
+
+#footer {
+ text-align: center;
+}
diff --git a/public_html/skins/default/images/logo_kolab.png b/public_html/skins/default/images/logo_kolab.png
new file mode 100644
index 0000000..0c06ff1
Binary files /dev/null and b/public_html/skins/default/images/logo_kolab.png differ
diff --git a/public_html/skins/default/templates/signup.html b/public_html/skins/default/templates/signup.html
new file mode 100644
index 0000000..66a649a
--- /dev/null
+++ b/public_html/skins/default/templates/signup.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>{$engine->translate('signup.headline')}</title>
+ <link rel="stylesheet" href="{$skin_path}style.css" />
+ <link rel="stylesheet" href="{$skin_path}hosted.css" />
+ <link rel="shortcut icon" type="image/png" href="{$skin_path}images/favicon.png" />
+ <script src="js/jquery.min.js"></script>
+ <script src="js/kolab_admin.js"></script>
+ <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
+ <script src="js/kolab_hosted.js"></script>
+ <script src="{$skin_path}ui.js"></script>
+</head>
+<body>
+ <div id="bodybox">
+ <div id="logo"></div>
+ <div id="content">
+ <div id="task_content" class="signup">
+ <h1>{$engine->translate('signup.headline')}</h1>
+ <p>{$engine->translate('signup.intro1')}</p>
+ <p>{$engine->translate('signup.intro2')}</p>
+ <div id="taskcontent" class="signup">{$form}</div>
+ </div>
+ </div>
+ <div id="footer">
+ {include file="signup_footer.html"}
+ </div>
+ </div>
+{$script}
+</body>
+</html>
diff --git a/public_html/skins/default/templates/signup_footer.html b/public_html/skins/default/templates/signup_footer.html
new file mode 100644
index 0000000..24d972d
--- /dev/null
+++ b/public_html/skins/default/templates/signup_footer.html
@@ -0,0 +1 @@
+{$engine->translate('signup.footer')}
diff --git a/public_html/skins/default/ui.js b/public_html/skins/default/ui.js
index c0dc901..45bfd51 100644
--- a/public_html/skins/default/ui.js
+++ b/public_html/skins/default/ui.js
@@ -153,7 +153,7 @@ function ui_resize()
var h = $('#content').height();
// resize UI elements
if (h - 22 > 380) {
- $('#taskcontent').css({'min-height': h - 22});
+ $('#taskcontent:not(.signup)').css({'min-height': h - 22});
}
};
diff --git a/public_html/skins/kolabsys/hosted.css b/public_html/skins/kolabsys/hosted.css
new file mode 100644
index 0000000..427d57d
--- /dev/null
+++ b/public_html/skins/kolabsys/hosted.css
@@ -0,0 +1,26 @@
+body {
+ background: #F3F3F3;
+ text-align: center;
+}
+
+#taskcontent {
+ width: 680px;
+ min-height: 100px;
+ max-height: 460px;
+}
+
+form#signup-form {
+ padding-top: 10px;
+}
+
+td.value input {
+ width: 250px;
+}
+
+td.label {
+ vertical-align: top;
+}
+
+table.form td {
+ text-align: left;
+}
diff --git a/public_html/skins/kolabsys/style.css b/public_html/skins/kolabsys/style.css
new file mode 120000
index 0000000..2bc3133
--- /dev/null
+++ b/public_html/skins/kolabsys/style.css
@@ -0,0 +1 @@
+../default/style.css
\ No newline at end of file
diff --git a/public_html/skins/kolabsys/templates/signup.html b/public_html/skins/kolabsys/templates/signup.html
new file mode 100644
index 0000000..7c756ae
--- /dev/null
+++ b/public_html/skins/kolabsys/templates/signup.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>Sign Up For Hosted Kolab</title>
+ <link rel="stylesheet" href="{$skin_path}style.css" />
+ <link rel="stylesheet" href="{$skin_path}hosted.css" />
+ <link rel="shortcut icon" type="image/png" href="{$skin_path}images/favicon.png" />
+ <script src="js/jquery.min.js"></script>
+ <script src="js/kolab_admin.js"></script>
+ <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
+ <script src="js/kolab_hosted.js"></script>
+ <script src="{$skin_path}ui.js"></script>
+</head>
+<body>
+ <div id="taskcontent" class="signup">{$form}</div>
+
+ {$script}
+</body>
+</html>
diff --git a/public_html/skins/kolabsys/ui.js b/public_html/skins/kolabsys/ui.js
new file mode 120000
index 0000000..b845f3f
--- /dev/null
+++ b/public_html/skins/kolabsys/ui.js
@@ -0,0 +1 @@
+../default/ui.js
\ No newline at end of file
diff --git a/public_html/skins/minimal/hosted.css b/public_html/skins/minimal/hosted.css
new file mode 120000
index 0000000..a66df34
--- /dev/null
+++ b/public_html/skins/minimal/hosted.css
@@ -0,0 +1 @@
+../default/hosted.css
\ No newline at end of file
diff --git a/public_html/skins/minimal/style.css b/public_html/skins/minimal/style.css
new file mode 120000
index 0000000..2bc3133
--- /dev/null
+++ b/public_html/skins/minimal/style.css
@@ -0,0 +1 @@
+../default/style.css
\ No newline at end of file
diff --git a/public_html/skins/minimal/templates/signup.html b/public_html/skins/minimal/templates/signup.html
new file mode 100644
index 0000000..ccf16b8
--- /dev/null
+++ b/public_html/skins/minimal/templates/signup.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <title>Sign Up For Hosted Kolab</title>
+ <link rel="stylesheet" href="{$skin_path}style.css" />
+ <link rel="stylesheet" href="{$skin_path}hosted.css" />
+ <link rel="shortcut icon" type="image/png" href="{$skin_path}images/favicon.png" />
+ <script src="js/jquery.min.js"></script>
+ <script src="js/kolab_admin.js"></script>
+ <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
+ <script src="js/kolab_hosted.js"></script>
+ <script src="{$skin_path}ui.js"></script>
+</head>
+<body>
+ <div id="taskcontent" class="signup">{$form}</div>
+
+ <div id="footer">
+ {include file="signup_footer.html"}
+ </div>
+{$script}
+</body>
+</html>
diff --git a/public_html/skins/minimal/templates/signup_footer.html b/public_html/skins/minimal/templates/signup_footer.html
new file mode 100644
index 0000000..4b6bac5
--- /dev/null
+++ b/public_html/skins/minimal/templates/signup_footer.html
@@ -0,0 +1 @@
+This is a service offered by <a href="http://kolabsys.com">Kolab Systems</a>.
diff --git a/public_html/skins/minimal/ui.js b/public_html/skins/minimal/ui.js
new file mode 120000
index 0000000..b845f3f
--- /dev/null
+++ b/public_html/skins/minimal/ui.js
@@ -0,0 +1 @@
+../default/ui.js
\ No newline at end of file
More information about the commits
mailing list