- updated readme and env.example

- fix some language validator inconsistencies
- added admin notifications
- added possiblity for users to delete their account
- added back index page
- works with mod_admin_rest version [afc42d7](afc42d70f0)
This commit is contained in:
Alexander Schäferdiek 2016-07-10 20:45:42 +02:00
parent f0643ce999
commit 9f085ca304
15 changed files with 289 additions and 56 deletions

View file

@ -63,7 +63,20 @@ as dependencies.
* Change directory to project home * Change directory to project home
* `git pull` * `git pull`
* `composer update` * `composer update`
* look for changes
* `php bin/phpmig migrate` * `php bin/phpmig migrate`
## Translations ## ## Translations ##
This app uses Symfony Translator. It's bootstraped in `Util\TranslationHelper` and locales are placed under `data/locale/`. Adjust to your needs or help translating. This app uses Symfony Translator. It's bootstraped in `Util\TranslationHelper` and locales are placed under `data/locale/`. Adjust to your needs or help translating.
## Changelog ##
- 0.1.1:
- updated readme and `env.example`
- fix some language validator inconsistencies
- added admin notifications
- added possiblity for users to delete their account
- added back index page
- works with mod_admin_rest version [afc42d7](https://github.com/snowblindroan/mod_admin_rest/commit/afc42d70f0aceb2351a1bc786d61e3f4dbdfb948)
- 0.1:
- initial release
- works with mod_admin_rest version [afc42d7](https://github.com/snowblindroan/mod_admin_rest/commit/afc42d70f0aceb2351a1bc786d61e3f4dbdfb948)

View file

@ -16,15 +16,18 @@ $container[InternalApplicationError::class] = function ($c) {
}; };
// pages // pages
$container[IndexAction::class] = function ($c) { $container[HomeAction::class] = function ($c) {
return new IndexAction($c->get('view'), $c->get('logger'), $c->get('flash'), $c->get('translator')); return new HomeAction($c->get('view'), $c->get('logger'), $c->get('flash'), $c->get('translator'));
}; };
$container[SignUpAction::class] = function ($c) { $container[SignUpAction::class] = function ($c) {
return new SignUpAction($c->get('view'), $c->get('logger'), $c->get('flash'), $c->get('translator')); return new SignUpAction($c->get('view'), $c->get('logger'), $c->get('flash'), $c->get('translator'), $c->get('router'));
}; };
$container[VerificationAction::class] = function ($c) { $container[VerificationAction::class] = function ($c) {
return new VerificationAction($c->get('view'), $c->get('logger'), $c->get('flash'), $c->get('translator')); return new VerificationAction($c->get('view'), $c->get('logger'), $c->get('flash'), $c->get('translator'));
}; };
$container[DeleteAction::class] = function ($c) {
return new DeleteAction($c->get('view'), $c->get('logger'), $c->get('flash'), $c->get('translator'));
};
// Routes // Routes
// error // error
@ -34,6 +37,7 @@ $app->get('/404', NotFoundAction::class)->setName('404');
$app->get('/500', InternalApplicationError::class)->setName('500'); $app->get('/500', InternalApplicationError::class)->setName('500');
// pages // pages
$app->get('/', IndexAction::class)->setName('/'); $app->get('/', HomeAction::class)->setName('/');
$app->map(['GET', 'POST'], '/signup', SignUpAction::class)->setName('signup'); $app->map(['GET', 'POST'], '/signup', SignUpAction::class)->setName('signup');
$app->get('/verification/{verificationCode}', VerificationAction::class)->setName('verification'); $app->get('/verification/{verificationCode}', VerificationAction::class)->setName('verification');
$app->map(['GET', 'POST'], '/delete', DeleteAction::class)->setName('delete');

View file

@ -1,6 +1,8 @@
# site settings # site settings
site_title="" site_title=""
site_navbar_index_displayname="Sign Up" site_navbar_home_displayname="Home"
site_navbar_signup_displayname="Sign up"
site_navbar_delete_displayname="Delete Account"
site_navbar_backlink_enabled="false" # enables a link in the navbar to go back to e.g. main server site site_navbar_backlink_enabled="false" # enables a link in the navbar to go back to e.g. main server site
site_navbar_backlink_uri="" site_navbar_backlink_uri=""
site_navbar_backlink_displayname="" site_navbar_backlink_displayname=""
@ -10,16 +12,21 @@ site_xmpp_server_displayname="jabber.server.org"
verification_cleanup_time="7 day" verification_cleanup_time="7 day"
# mod_admin_rest Settings # mod_admin_rest Settings
xmpp_curl_uri="/admin_rest" # uri to admin_rest xmpp_curl_uri="/admin_rest" # full uri to admin_rest
xmpp_curl_auth_admin_username="" # configured in prosody lua file xmpp_curl_auth_admin_username="" # configured in prosody lua file
xmpp_curl_auth_admin_password="" # configured in prosody lua file xmpp_curl_auth_admin_password="" # configured in prosody lua file
# Mail Settings # Mail Settings
# main
mail_host="" mail_host=""
mail_port="587" mail_port="587"
mail_secure="tls" mail_secure="tls"
mail_auth="true" mail_auth=true
mail_username="" mail_username=""
mail_password="" mail_password=""
mail_from="webmaster@jabber.server.org" mail_from="webmaster@jabber.server.org"
mail_from_name="jabber.server.org" mail_from_name="jabber.server.org"
# notification
mail_notify="true" # sends an email to mail_notify_to if a new user successfully verified their account
mail_notify_to=${mail_from} # defaults to sender mail, e.g. webmaster, maybe change this e.g. to "xx@xx"

View file

@ -1,3 +1,9 @@
# Home
home.title: Home
home.text: |
Hi,
welcome to the free jabber service %server%. Sign up now by clicking the "Sign up" button in the navigation bar.
# Sign up # Sign up
sign.up.title: Sign Up sign.up.title: Sign Up
sign.up.flash.success: Signed up successfully. Check your inbox. sign.up.flash.success: Signed up successfully. Check your inbox.
@ -13,7 +19,7 @@ sign.up.form.password: Password:
sign.up.form.password.placeholder: Password: sign.up.form.password.placeholder: Password:
# Verification # Verification
verification.mail.subject: %server% jabber account verification verification.mail.subject: %server%: jabber account verification
verification.mail.body: | verification.mail.body: |
Hello %username%, Hello %username%,
you've signed up for a jabber account on %server%. you've signed up for a jabber account on %server%.
@ -22,14 +28,29 @@ verification.code.invalid: Verification code %verificationCode% is not valid.
verification.flash.already_in_use_username: %username% is already in use. verification.flash.already_in_use_username: %username% is already in use.
verification.flash.success: Verification successful. You can now sign in to your newly created jabber account %username%@hoth.one. verification.flash.success: Verification successful. You can now sign in to your newly created jabber account %username%@hoth.one.
verification.flash.unknown_error: Could not process sign up of %username%. Please contact administrator. verification.flash.unknown_error: Could not process sign up of %username%. Please contact administrator.
verification.mail.success.subject: %server% jabber account information verification.mail.success.subject: %server%: jabber account information
verification.mail.success.body: | verification.mail.success.body: |
Hello %username%, Hello %username%,
you've verified your email address successfully and your jabber account on %server% has been created. you've verified your email address successfully and your jabber account on %server% has been created.
Your password is "%password%". Keep this mail safe! Your password is "%password%".
If you wish to delete your account, use %deleteCode% on the website.
Keep this mail safe!
verification.mail.success.notify.subject: %server%: user verified their account
verification.mail.success.notify.body: A user (%email%) verified their account %username%@%server% successfully.
# Delete
delete.title: Delete Account
delete.form.username: Username:
delete.form.username.placeholder: username
delete.form.delete_code: Deletion Code:
delete.form.delete_code.placeholder: received via mail on sign up, 32 in length
delete.form.button: Delete
delete.flash.combination_not_found: Could not find a combination match for username and delete code.
delete.flash.success: Successfully deleted your account %username%@%server%.
delete.flash.unknown_error: Could not process deletion of %username%. Please contact administrator.
# Cleanup # Cleanup
cleanup.mail.subject: %server% jabber account verification expired cleanup.mail.subject: %server%: jabber account verification expired
cleanup.mail.body: | cleanup.mail.body: |
Hello %username%, Hello %username%,
you've recently signed up for a jabber account on %server% but you did not verify your account within 7 days. you've recently signed up for a jabber account on %server% but you did not verify your account within 7 days.
@ -42,6 +63,8 @@ log.verification.invalid: Tried to use code %verificationCode% but it is invalid
log.verification.sucess: %username% verified. log.verification.sucess: %username% verified.
log.verification.unknown_error: Unknown error in XMPP Rest API. log.verification.unknown_error: Unknown error in XMPP Rest API.
log.verification.cleanup: %username% did not verify. Deleted. log.verification.cleanup: %username% did not verify. Deleted.
log.delete.success: %username% deleted their account.
log.delete.unknown_error: Unknown error in XMPP Rest API.
# Error # Error
error.401.title: 401 error.401.title: 401

View file

@ -0,0 +1,35 @@
<?php
use Phpmig\Migration\Migration;
class UsersRegisteredTable extends Migration
{
public $tableName = 'users_registered'; // Table name
public $db;
/**
* Do the migration
*/
public function up()
{
$this->db->create($this->tableName, function($table) {
$table->string('username')->unique()->primary();
$table->string('delete_code', 64);
});
}
/**
* Undo the migration
*/
public function down()
{
$this->db->dropIfExists($this->tableName);
}
/**
* Init the migration
*/
public function init()
{
$this->db = $this->container['schema'];
}
}

View file

@ -0,0 +1,85 @@
<?php
use Curl\Curl;
use Psr\Log\LoggerInterface;
use Slim\Flash\Messages;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Views\Twig;
use Symfony\Component\Translation\Translator;
final class DeleteAction
{
private $view;
private $translator;
private $logger;
private $flash;
public function __construct(Twig $view, LoggerInterface $logger, Messages $flash, Translator $translator)
{
$this->view = $view;
$this->translator = $translator;
$this->logger = $logger;
$this->flash = $flash;
}
public function __invoke(Request $request, Response $response, $args)
{
$body = $request->getParsedBody();
if ($request->isPost()) {
// Form validation
$validator = new Validator();
$validator->filter_rules([
'username' => 'trim|sanitize_string',
'delete_code' => 'trim|sanitize_string',
]);
$validator->validation_rules([
'username' => 'required|alpha_numeric|max_len,64|min_len,3',
'delete_code' => 'required|exact_len,64',
]);
if (!$validator->run($body)) {
$validator->addErrorsToFlashMessage($this->flash);
return $response->withRedirect('/delete');
}
$username = $body['username'];
$deleteCode = $body['delete_code'];
// check if combination matches
$usersRegistered = UserRegistered::with([])->where('username', $username)->where('delete_code', $deleteCode)->get();
if (empty($usersRegistered) || $usersRegistered->count() == 0) {
$this->flash->addMessage('error', $this->translator->trans('delete.flash.combination_not_found'));
return $response->withRedirect('/delete');
} else {
$userRegistered = $usersRegistered->pop();
$curl = new Curl();
$curl->setBasicAuthentication(getenv('xmpp_curl_auth_admin_username'), getenv('xmpp_curl_auth_admin_password'));
$curl->delete(getenv('xmpp_curl_uri') . '/user/' . $username);
$curl->close();
if ($curl->http_status_code == 200) {
$userRegistered->delete();
$this->flash->addMessage('success', $this->translator->trans('delete.flash.success', ['%username%' => $username, '%server%' => getenv('site_xmpp_server_displayname')]));
$this->logger->info($this->translator->trans('log.delete.success', ['%username%' => $username]));
return $response->withRedirect('/');
} else {
$this->flash->addMessage('error', $this->translator->trans('delete.flash.unknown_error', ['%username%' => $username]));
$this->logger->warning($this->translator->trans('log.delete.flash.unknown_error'), ['code' => $curl->http_status_code, 'message' => $curl->http_error_message]);
return $response->withRedirect('/delete');
}
}
}
// render GET
$this->view->render($response, 'delete.twig', [
'title' => $this->translator->trans('delete.title'),
]);
return $response;
}
}

View file

@ -7,7 +7,7 @@ use Slim\Http\Request;
use Slim\Http\Response; use Slim\Http\Response;
use Symfony\Component\Translation\Translator; use Symfony\Component\Translation\Translator;
final class IndexAction final class HomeAction
{ {
private $view; private $view;
private $translator; private $translator;
@ -24,6 +24,9 @@ final class IndexAction
public function __invoke(Request $request, Response $response, $args) public function __invoke(Request $request, Response $response, $args)
{ {
return $response->withRedirect('/signup'); return $this->view->render($response, 'home.twig', [
'title' => $this->translator->trans('home.title'),
'content' => $this->translator->trans('home.text', ['%server%' => getenv('site_xmpp_server_displayname')])
]);
} }
} }

View file

@ -2,6 +2,7 @@
use Curl\Curl; use Curl\Curl;
use Slim\Flash\Messages; use Slim\Flash\Messages;
use Slim\Interfaces\RouterInterface;
use Slim\Views\Twig; use Slim\Views\Twig;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Slim\Http\Request; use Slim\Http\Request;
@ -14,13 +15,15 @@ final class SignUpAction
private $translator; private $translator;
private $logger; private $logger;
private $flash; private $flash;
private $router;
public function __construct(Twig $view, LoggerInterface $logger, Messages $flash, Translator $translator) public function __construct(Twig $view, LoggerInterface $logger, Messages $flash, Translator $translator, RouterInterface $router)
{ {
$this->view = $view; $this->view = $view;
$this->translator = $translator; $this->translator = $translator;
$this->logger = $logger; $this->logger = $logger;
$this->flash = $flash; $this->flash = $flash;
$this->router = $router;
} }
public function __invoke(Request $request, Response $response, $args) public function __invoke(Request $request, Response $response, $args)
@ -102,7 +105,11 @@ final class SignUpAction
$mailer->addAddress($userAwaiting->email); $mailer->addAddress($userAwaiting->email);
$verificationLink = $request->getUri()->getScheme() . '://' . $request->getUri()->getHost() . (!empty($p = $request->getUri()->getPort()) ? ':' .$p : '') .'/verification/' . $userAwaiting->verification_code; $verificationLink = $request->getUri()->getScheme();
$verificationLink .= '://';
$verificationLink .= $request->getUri()->getHost();
$verificationLink .= (!empty($p = $request->getUri()->getPort()) ? ':' .$p : '');
$verificationLink .= $this->router->pathFor('verification', ['verificationCode' => $userAwaiting->verification_code]);
$mailer->Subject = $this->translator->trans('verification.mail.subject', ['%server%' => getenv('site_xmpp_server_displayname')]); $mailer->Subject = $this->translator->trans('verification.mail.subject', ['%server%' => getenv('site_xmpp_server_displayname')]);
$mailer->Body = $this->translator->trans('verification.mail.body', ['%username%' => $userAwaiting->username, '%verificationLink%' => $verificationLink, '%server%' => getenv('site_xmpp_server_displayname')]); $mailer->Body = $this->translator->trans('verification.mail.body', ['%username%' => $userAwaiting->username, '%verificationLink%' => $verificationLink, '%server%' => getenv('site_xmpp_server_displayname')]);

View file

@ -52,32 +52,53 @@ final class VerificationAction
$this->flash->addMessage('success', $this->translator->trans('verification.flash.success', ['%username%' => $userAwaiting->username])); $this->flash->addMessage('success', $this->translator->trans('verification.flash.success', ['%username%' => $userAwaiting->username]));
$this->logger->info($this->translator->trans('log.verification.sucess', ['%username%' => $userAwaiting->username])); $this->logger->info($this->translator->trans('log.verification.sucess', ['%username%' => $userAwaiting->username]));
if (getenv('mail_notify') == true) {
$mailer = new PHPMailer();
$mailer->CharSet = 'UTF-8';
$mailer->ContentType = 'text/plain';
$mailer->isSMTP();
$mailer->SMTPSecure = getenv('mail_secure');
$mailer->SMTPAuth = getenv('mail_auth');
$mailer->Host = getenv('mail_host');
$mailer->Port = getenv('mail_port');
$mailer->Username = getenv('mail_username');
$mailer->Password = getenv('mail_password');
$mailer->From = getenv('mail_from');
$mailer->FromName = getenv('mail_from_name');
$mailer->addAddress(getenv('mail_notify_to'));
$mailer->Subject = $this->translator->trans('verification.mail.success.notify.subject', ['%server%' => getenv('site_xmpp_server_displayname')]);
$mailer->Body = $this->translator->trans('verification.mail.success.notify.body', ['%username%' => $userAwaiting->username, '%server%' => getenv('site_xmpp_server_displayname'), '%email%' => $userAwaiting->email]);
$mailer->send();
}
$userRegistered = new UserRegistered();
$userRegistered->username = $userAwaiting->username;
$userRegistered->delete_code = hash('sha256', (time() . $userAwaiting->username . rand()));
$userRegistered->save();
$mailer = new PHPMailer(); $mailer = new PHPMailer();
$mailer->CharSet = 'UTF-8'; $mailer->CharSet = 'UTF-8';
$mailer->ContentType = 'text/plain'; $mailer->ContentType = 'text/plain';
$mailer->isSMTP(); $mailer->isSMTP();
$mailer->SMTPSecure = getenv('mail_secure'); $mailer->SMTPSecure = getenv('mail_secure');
$mailer->SMTPAuth = getenv('mail_auth'); $mailer->SMTPAuth = getenv('mail_auth');
$mailer->Host = getenv('mail_host'); $mailer->Host = getenv('mail_host');
$mailer->Port = getenv('mail_port'); $mailer->Port = getenv('mail_port');
$mailer->Username = getenv('mail_username'); $mailer->Username = getenv('mail_username');
$mailer->Password = getenv('mail_password'); $mailer->Password = getenv('mail_password');
$mailer->From = getenv('mail_from'); $mailer->From = getenv('mail_from');
$mailer->FromName = getenv('mail_from_name'); $mailer->FromName = getenv('mail_from_name');
$mailer->addAddress($userAwaiting->email); $mailer->addAddress($userAwaiting->email);
$mailer->Subject = $this->translator->trans('verification.mail.success.subject', ['%server%' => getenv('site_xmpp_server_displayname')]); $mailer->Subject = $this->translator->trans('verification.mail.success.subject', ['%server%' => getenv('site_xmpp_server_displayname')]);
$mailer->Body = $this->translator->trans('verification.mail.success.body', ['%username%' => $userAwaiting->username, '%server%' => getenv('site_xmpp_server_displayname'), '%password%' => $userAwaiting->password]); $mailer->Body = $this->translator->trans('verification.mail.success.body', ['%username%' => $userAwaiting->username, '%server%' => getenv('site_xmpp_server_displayname'), '%password%' => $userAwaiting->password, '%deleteCode%' => $userRegistered->delete_code]);
$mailer->send(); $mailer->send();
$userAwaiting->delete(); $userAwaiting->delete();
return $response->withRedirect('/signup'); return $response->withRedirect('/');
} else { } else {
$this->flash->addMessage('error', $this->translator->trans('verification.flash.unknown_error', ['%username%' => $userAwaiting->username])); $this->flash->addMessage('error', $this->translator->trans('verification.flash.unknown_error', ['%username%' => $userAwaiting->username]));
$this->logger->warning($this->translator->trans('verification.flash.unknown_error'), ['code' => $curl->http_status_code, 'message' => $curl->http_error_message]); $this->logger->warning($this->translator->trans('verification.flash.unknown_error'), ['code' => $curl->http_status_code, 'message' => $curl->http_error_message]);
return $response->withRedirect('/signup'); return $response->withRedirect('/');
} }
} }
} }

View file

@ -0,0 +1,9 @@
<?php
use Illuminate\Database\Eloquent\Model;
class UserRegistered extends Model
{
public $table = 'users_registered';
public $primaryKey = 'username';
public $timestamps = false;
}

View file

@ -93,86 +93,86 @@ class Validator extends GUMP
switch ($e['rule']) { switch ($e['rule']) {
case 'mismatch' : case 'mismatch' :
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_required': case 'validate_required':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_valid_json_string': case 'validate_valid_json_string':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_valid_email': case 'validate_valid_email':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_max_len': case 'validate_max_len':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_min_len': case 'validate_min_len':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_exact_len': case 'validate_exact_len':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_alpha': case 'validate_alpha':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_alpha_numeric': case 'validate_alpha_numeric':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_alpha_dash': case 'validate_alpha_dash':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_numeric': case 'validate_numeric':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_integer': case 'validate_integer':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_boolean': case 'validate_boolean':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_float': case 'validate_float':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_valid_url': case 'validate_valid_url':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_url_exists': case 'validate_url_exists':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_valid_ip': case 'validate_valid_ip':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_valid_cc': case 'validate_valid_cc':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_valid_name': case 'validate_valid_name':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_contains': case 'validate_contains':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => implode(', ', $param)]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => implode(', ', $param)]);
break; break;
case 'validate_street_address': case 'validate_street_address':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_date': case 'validate_date':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_min_numeric': case 'validate_min_numeric':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_max_numeric': case 'validate_max_numeric':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_equals': case 'validate_equals':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
case 'validate_set_min_len': case 'validate_set_min_len':
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
break; break;
default: default:
$resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param' => $param]); $resp[$field] = $this->translator->trans($e['rule'], ['%field%' => $field, '%param%' => $param]);
} }
} }

View file

@ -23,9 +23,11 @@
<!-- Navigation --> <!-- Navigation -->
<nav id="nav-left"> <nav id="nav-left">
<div id="nav-list"> <div id="nav-list">
<a href="/">{{ getenv('site_navbar_index_displayname') }}</a> <a href="{{ base_url() }}{{ path_for('/') }}">{{ getenv('site_navbar_home_displayname') }}</a>
<a href="{{ base_url() }}{{ path_for('signup') }}">{{ getenv('site_navbar_signup_displayname') }}</a>
<a href="{{ base_url() }}{{ path_for('delete') }}">{{ getenv('site_navbar_delete_displayname') }}</a>
{% if getenv('site_navbar_backlink_enabled') %} {% if getenv('site_navbar_backlink_enabled') == 'true' %}
<br /> <br />
<br /> <br />
<a href="{{ getenv('site_navbar_backlink_uri') }}">{{ getenv('site_navbar_backlink_displayname') }}</a> <a href="{{ getenv('site_navbar_backlink_uri') }}">{{ getenv('site_navbar_backlink_displayname') }}</a>
@ -97,9 +99,9 @@
<script src="{{ base_url() }}/js/main.js"></script> <script src="{{ base_url() }}/js/main.js"></script>
<script> <script>
$(".alert-danger" ).delay(20000).fadeOut(300); $(".alert-danger" ).delay(30000).fadeOut(300);
$(".alert-success" ).delay(5000).fadeOut(300); $(".alert-success" ).delay(10000).fadeOut(300);
$(".alert-info" ).delay(5000).fadeOut(300); $(".alert-info" ).delay(10000).fadeOut(300);
</script> </script>
</div> </div>

15
src/View/delete.twig Normal file
View file

@ -0,0 +1,15 @@
{% extends 'base.twig' %}
{% block content %}
<form class="" role="form" name="delete" id="delete" method="post">
<h1>{{ title }}</h1>
<label for="username">{% trans %}delete.form.username{% endtrans %}</label><br/>
<input type="text" id="username" name="username" class="" placeholder="{% trans %}delete.form.username.placeholder{% endtrans %}" value="" autofocus required> @{{ getenv('site_xmpp_server_displayname') }}
<br/><br/>
<label for="deletion_code">{% trans %}delete.form.delete_code{% endtrans %}</label><br/>
<input type="text" id="delete_code" name="delete_code" class="" placeholder="{% trans %}delete.form.delete_code.placeholder{% endtrans %}" value="" autofocus required>
<br/><br/>
<input class="" type="submit" name="delete" value="{% trans %}delete.form.button{% endtrans %}"/>
</form>
{% endblock %}

8
src/View/home.twig Normal file
View file

@ -0,0 +1,8 @@
{% extends 'base.twig' %}
{% block content %}
<h1 class="header">{{ title }}</h1>
{{ content|nl2br }}
{% endblock %}

View file

@ -3,6 +3,7 @@
{% block content %} {% block content %}
<form class="" role="form" name="register" id="register" method="post"> <form class="" role="form" name="register" id="register" method="post">
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
<label for="username">{% trans %}sign.up.form.username{% endtrans %}</label><br/> <label for="username">{% trans %}sign.up.form.username{% endtrans %}</label><br/>
<input type="text" id="username" name="username" class="" placeholder="{% trans %}sign.up.form.username.placeholder{% endtrans %}" value="" autofocus required> @{{ getenv('site_xmpp_server_displayname') }} <input type="text" id="username" name="username" class="" placeholder="{% trans %}sign.up.form.username.placeholder{% endtrans %}" value="" autofocus required> @{{ getenv('site_xmpp_server_displayname') }}
<br/><br/> <br/><br/>