forked from I2P_Developers/i2p.i2p
- Add password enabled property
- Bypass nonce checking if passwords enabled - Add message about cookies if nonce fails - Minor susidns cleanup
This commit is contained in:
@ -93,9 +93,6 @@ public class IndexBean {
|
|||||||
public static final int NOT_RUNNING = 3;
|
public static final int NOT_RUNNING = 3;
|
||||||
public static final int STANDBY = 4;
|
public static final int STANDBY = 4;
|
||||||
|
|
||||||
/** deprecated unimplemented, now using routerconsole realm */
|
|
||||||
//public static final String PROP_TUNNEL_PASSPHRASE = "i2ptunnel.passphrase";
|
|
||||||
public static final String PROP_TUNNEL_PASSPHRASE = "consolePassword";
|
|
||||||
//static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
|
//static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
|
||||||
//static final String PROP_NONCE_OLD = PROP_NONCE + '2';
|
//static final String PROP_NONCE_OLD = PROP_NONCE + '2';
|
||||||
/** 3 wasn't enough for some browsers. They are reloading the page for some reason - maybe HEAD? @since 0.8.1 */
|
/** 3 wasn't enough for some browsers. They are reloading the page for some reason - maybe HEAD? @since 0.8.1 */
|
||||||
@ -108,6 +105,7 @@ public class IndexBean {
|
|||||||
public static final String DEFAULT_THEME = "light";
|
public static final String DEFAULT_THEME = "light";
|
||||||
public static final String PROP_CSS_DISABLED = "routerconsole.css.disabled";
|
public static final String PROP_CSS_DISABLED = "routerconsole.css.disabled";
|
||||||
public static final String PROP_JS_DISABLED = "routerconsole.javascript.disabled";
|
public static final String PROP_JS_DISABLED = "routerconsole.javascript.disabled";
|
||||||
|
private static final String PROP_PW_ENABLE = "routerconsole.auth.enable";
|
||||||
|
|
||||||
public IndexBean() {
|
public IndexBean() {
|
||||||
_context = I2PAppContext.getGlobalContext();
|
_context = I2PAppContext.getGlobalContext();
|
||||||
@ -149,14 +147,11 @@ public class IndexBean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** deprecated unimplemented, now using routerconsole realm */
|
|
||||||
public void setPassphrase(String phrase) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAction(String action) {
|
public void setAction(String action) {
|
||||||
if ( (action == null) || (action.trim().length() <= 0) ) return;
|
if ( (action == null) || (action.trim().length() <= 0) ) return;
|
||||||
_action = action;
|
_action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTunnel(String tunnel) {
|
public void setTunnel(String tunnel) {
|
||||||
if ( (tunnel == null) || (tunnel.trim().length() <= 0) ) return;
|
if ( (tunnel == null) || (tunnel.trim().length() <= 0) ) return;
|
||||||
try {
|
try {
|
||||||
@ -166,17 +161,15 @@ public class IndexBean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** just check if console password option is set, jetty will do auth */
|
|
||||||
private boolean validPassphrase() {
|
|
||||||
String pass = _context.getProperty(PROP_TUNNEL_PASSPHRASE);
|
|
||||||
return pass != null && pass.trim().length() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String processAction() {
|
private String processAction() {
|
||||||
if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action)))
|
if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action)))
|
||||||
return "";
|
return "";
|
||||||
if ( (!haveNonce(_curNonce)) && (!validPassphrase()) )
|
// If passwords are turned on, all is assumed good
|
||||||
return _("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.");
|
if (!_context.getBooleanProperty(PROP_PW_ENABLE) &&
|
||||||
|
!haveNonce(_curNonce))
|
||||||
|
return _("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.")
|
||||||
|
+ ' ' +
|
||||||
|
_("If the problem persists, verify that you have cookies enabled in your browser.");
|
||||||
if ("Stop all".equals(_action))
|
if ("Stop all".equals(_action))
|
||||||
return stopAll();
|
return stopAll();
|
||||||
else if ("Start all".equals(_action))
|
else if ("Start all".equals(_action))
|
||||||
|
@ -105,11 +105,13 @@ public class ConsolePasswordManager extends RouterPasswordManager {
|
|||||||
// consolePassword
|
// consolePassword
|
||||||
String pw = _context.getProperty(PROP_CONSOLE_OLD);
|
String pw = _context.getProperty(PROP_CONSOLE_OLD);
|
||||||
if (pw != null) {
|
if (pw != null) {
|
||||||
|
Map toAdd = new HashMap(2);
|
||||||
if (pw.length() > 0) {
|
if (pw.length() > 0) {
|
||||||
saveMD5(RouterConsoleRunner.PROP_CONSOLE_PW, RouterConsoleRunner.JETTY_REALM,
|
saveMD5(RouterConsoleRunner.PROP_CONSOLE_PW, RouterConsoleRunner.JETTY_REALM,
|
||||||
CONSOLE_USER, pw);
|
CONSOLE_USER, pw);
|
||||||
|
toAdd.put(RouterConsoleRunner.PROP_PW_ENABLE, "true");
|
||||||
}
|
}
|
||||||
Map toAdd = Collections.singletonMap(PROP_MIGRATED, "true");
|
toAdd.put(PROP_MIGRATED, "true");
|
||||||
List toDel = Collections.singletonList(PROP_CONSOLE_OLD);
|
List toDel = Collections.singletonList(PROP_CONSOLE_OLD);
|
||||||
return _context.router().saveConfig(toAdd, toDel);
|
return _context.router().saveConfig(toAdd, toDel);
|
||||||
}
|
}
|
||||||
|
@ -177,17 +177,22 @@ public class FormHandler {
|
|||||||
_valid = false;
|
_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_nonce == null) {
|
|
||||||
//addFormError("You trying to mess with me? Huh? Are you?");
|
|
||||||
_valid = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// To prevent actions with GET, jsps must call storeMethod()
|
// To prevent actions with GET, jsps must call storeMethod()
|
||||||
if (_method != null && !"POST".equals(_method)) {
|
if (_method != null && !"POST".equals(_method)) {
|
||||||
addFormError("Invalid form submission, requires POST not " + _method);
|
addFormError("Invalid form submission, requires POST not " + _method);
|
||||||
_valid = false;
|
_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// If passwords are turned on, all is assumed good
|
||||||
|
if (_context.getBooleanProperty(RouterConsoleRunner.PROP_PW_ENABLE)) {
|
||||||
|
_valid = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_nonce == null) {
|
||||||
|
//addFormError("You trying to mess with me? Huh? Are you?");
|
||||||
|
_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String sharedNonce = System.getProperty("router.consoleNonce");
|
String sharedNonce = System.getProperty("router.consoleNonce");
|
||||||
if ( (sharedNonce != null) && (sharedNonce.equals(_nonce) ) ) {
|
if ( (sharedNonce != null) && (sharedNonce.equals(_nonce) ) ) {
|
||||||
@ -195,7 +200,9 @@ public class FormHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!_nonce.equals(_nonce1) && !_nonce.equals(_nonce2)) {
|
if (!_nonce.equals(_nonce1) && !_nonce.equals(_nonce2)) {
|
||||||
addFormError(_("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit."));
|
addFormError(_("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.")
|
||||||
|
+ ' ' +
|
||||||
|
_("If the problem persists, verify that you have cookies enabled in your browser."));
|
||||||
_valid = false;
|
_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
public static final String JETTY_REALM = "i2prouter";
|
public static final String JETTY_REALM = "i2prouter";
|
||||||
private static final String JETTY_ROLE = "routerAdmin";
|
private static final String JETTY_ROLE = "routerAdmin";
|
||||||
public static final String PROP_CONSOLE_PW = "routerconsole.auth." + JETTY_REALM;
|
public static final String PROP_CONSOLE_PW = "routerconsole.auth." + JETTY_REALM;
|
||||||
|
public static final String PROP_PW_ENABLE = "routerconsole.auth.enable";
|
||||||
|
|
||||||
public static final String ROUTERCONSOLE = "routerconsole";
|
public static final String ROUTERCONSOLE = "routerconsole";
|
||||||
public static final String PREFIX = "webapps.";
|
public static final String PREFIX = "webapps.";
|
||||||
@ -735,8 +736,13 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
SecurityHandler sec = new SecurityHandler();
|
SecurityHandler sec = new SecurityHandler();
|
||||||
List<ConstraintMapping> constraints = new ArrayList(4);
|
List<ConstraintMapping> constraints = new ArrayList(4);
|
||||||
ConsolePasswordManager mgr = new ConsolePasswordManager(ctx);
|
ConsolePasswordManager mgr = new ConsolePasswordManager(ctx);
|
||||||
|
boolean enable = ctx.getBooleanProperty(PROP_PW_ENABLE);
|
||||||
|
if (enable) {
|
||||||
Map<String, String> userpw = mgr.getMD5(PROP_CONSOLE_PW);
|
Map<String, String> userpw = mgr.getMD5(PROP_CONSOLE_PW);
|
||||||
if (!userpw.isEmpty()) {
|
if (userpw.isEmpty()) {
|
||||||
|
enable = false;
|
||||||
|
ctx.router().saveConfig(PROP_CONSOLE_PW, "false");
|
||||||
|
} else {
|
||||||
HashUserRealm realm = new HashUserRealm(JETTY_REALM);
|
HashUserRealm realm = new HashUserRealm(JETTY_REALM);
|
||||||
sec.setUserRealm(realm);
|
sec.setUserRealm(realm);
|
||||||
sec.setAuthenticator(authenticator);
|
sec.setAuthenticator(authenticator);
|
||||||
@ -753,6 +759,7 @@ public class RouterConsoleRunner implements RouterApp {
|
|||||||
constraints.add(cm);
|
constraints.add(cm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This forces a '403 Forbidden' response for TRACE and OPTIONS unless the
|
// This forces a '403 Forbidden' response for TRACE and OPTIONS unless the
|
||||||
// WAC handler handles it.
|
// WAC handler handles it.
|
||||||
|
@ -119,10 +119,10 @@ public class AddressbookBean extends BaseBean
|
|||||||
}
|
}
|
||||||
public String getBook()
|
public String getBook()
|
||||||
{
|
{
|
||||||
if( book == null || ( book.compareToIgnoreCase( "master" ) != 0 &&
|
if( book == null || ( !book.equalsIgnoreCase( "master" ) &&
|
||||||
book.compareToIgnoreCase( "router" ) != 0 &&
|
!book.equalsIgnoreCase( "router" ) &&
|
||||||
book.compareToIgnoreCase( "private" ) != 0 &&
|
!book.equalsIgnoreCase( "private" ) &&
|
||||||
book.compareToIgnoreCase( "published" ) != 0 ))
|
!book.equalsIgnoreCase( "published" )))
|
||||||
book = "router";
|
book = "router";
|
||||||
|
|
||||||
return book;
|
return book;
|
||||||
@ -252,7 +252,8 @@ public class AddressbookBean extends BaseBean
|
|||||||
String message = "";
|
String message = "";
|
||||||
|
|
||||||
if( action != null ) {
|
if( action != null ) {
|
||||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
if (_context.getBooleanProperty(PROP_PW_ENABLE) ||
|
||||||
|
(serial != null && serial.equals(lastSerial))) {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if (action.equals(_("Add")) || action.equals(_("Replace"))) {
|
if (action.equals(_("Add")) || action.equals(_("Replace"))) {
|
||||||
if( addressbook != null && hostname != null && destination != null ) {
|
if( addressbook != null && hostname != null && destination != null ) {
|
||||||
@ -336,7 +337,9 @@ public class AddressbookBean extends BaseBean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
|
||||||
|
+ ' ' +
|
||||||
|
_("If the problem persists, verify that you have cookies enabled in your browser.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,22 +367,22 @@ public class AddressbookBean extends BaseBean
|
|||||||
|
|
||||||
public boolean isMaster()
|
public boolean isMaster()
|
||||||
{
|
{
|
||||||
return getBook().compareToIgnoreCase( "master" ) == 0;
|
return getBook().equalsIgnoreCase("master");
|
||||||
}
|
}
|
||||||
public boolean isRouter()
|
public boolean isRouter()
|
||||||
{
|
{
|
||||||
return getBook().compareToIgnoreCase( "router" ) == 0;
|
return getBook().equalsIgnoreCase("router");
|
||||||
}
|
}
|
||||||
public boolean isPublished()
|
public boolean isPublished()
|
||||||
{
|
{
|
||||||
return getBook().compareToIgnoreCase( "published" ) == 0;
|
return getBook().equalsIgnoreCase("published");
|
||||||
}
|
}
|
||||||
public boolean isPrivate()
|
public boolean isPrivate()
|
||||||
{
|
{
|
||||||
return getBook().compareToIgnoreCase( "private" ) == 0;
|
return getBook().equalsIgnoreCase("private");
|
||||||
}
|
}
|
||||||
public void setFilter(String filter) {
|
public void setFilter(String filter) {
|
||||||
if( filter != null && ( filter.length() == 0 || filter.compareToIgnoreCase( "none" ) == 0 ) ) {
|
if( filter != null && ( filter.length() == 0 || filter.equalsIgnoreCase("none"))) {
|
||||||
filter = null;
|
filter = null;
|
||||||
search = null;
|
search = null;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import net.i2p.I2PAppContext;
|
|||||||
*/
|
*/
|
||||||
public class BaseBean
|
public class BaseBean
|
||||||
{
|
{
|
||||||
private final I2PAppContext _context;
|
protected final I2PAppContext _context;
|
||||||
protected final Properties properties;
|
protected final Properties properties;
|
||||||
|
|
||||||
private long configLastLoaded = 0;
|
private long configLastLoaded = 0;
|
||||||
@ -26,6 +26,7 @@ public class BaseBean
|
|||||||
public static final String PROP_THEME_NAME = "theme";
|
public static final String PROP_THEME_NAME = "theme";
|
||||||
public static final String DEFAULT_THEME = "light";
|
public static final String DEFAULT_THEME = "light";
|
||||||
public static final String BASE_THEME_PATH = "/themes/susidns/";
|
public static final String BASE_THEME_PATH = "/themes/susidns/";
|
||||||
|
public static final String PROP_PW_ENABLE = "routerconsole.auth.enable";
|
||||||
|
|
||||||
public BaseBean()
|
public BaseBean()
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,8 @@ public class ConfigBean implements Serializable {
|
|||||||
public String getMessages() {
|
public String getMessages() {
|
||||||
String message = "";
|
String message = "";
|
||||||
if( action != null ) {
|
if( action != null ) {
|
||||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
if (I2PAppContext.getGlobalContext().getBooleanProperty(BaseBean.PROP_PW_ENABLE) ||
|
||||||
|
(serial != null && serial.equals(lastSerial))) {
|
||||||
if(action.equals(_("Save"))) {
|
if(action.equals(_("Save"))) {
|
||||||
save();
|
save();
|
||||||
message = _("Configuration saved.");
|
message = _("Configuration saved.");
|
||||||
@ -145,7 +146,9 @@ public class ConfigBean implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
|
||||||
|
+ ' ' +
|
||||||
|
_("If the problem persists, verify that you have cookies enabled in your browser.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( message.length() > 0 )
|
if( message.length() > 0 )
|
||||||
|
@ -28,7 +28,6 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
|
||||||
import net.i2p.client.naming.NamingService;
|
import net.i2p.client.naming.NamingService;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
@ -128,7 +127,7 @@ public class NamingServiceBean extends AddressbookBean
|
|||||||
/** @return the NamingService for the current file name, or the root NamingService */
|
/** @return the NamingService for the current file name, or the root NamingService */
|
||||||
private NamingService getNamingService()
|
private NamingService getNamingService()
|
||||||
{
|
{
|
||||||
NamingService root = I2PAppContext.getGlobalContext().namingService();
|
NamingService root = _context.namingService();
|
||||||
NamingService rv = searchNamingService(root, getFileName());
|
NamingService rv = searchNamingService(root, getFileName());
|
||||||
return rv != null ? rv : root;
|
return rv != null ? rv : root;
|
||||||
}
|
}
|
||||||
@ -173,7 +172,7 @@ public class NamingServiceBean extends AddressbookBean
|
|||||||
for (Map.Entry<String, Destination> entry : results.entrySet()) {
|
for (Map.Entry<String, Destination> entry : results.entrySet()) {
|
||||||
String name = entry.getKey();
|
String name = entry.getKey();
|
||||||
if( filter != null && filter.length() > 0 ) {
|
if( filter != null && filter.length() > 0 ) {
|
||||||
if( filter.compareTo( "0-9" ) == 0 ) {
|
if (filter.equals("0-9")) {
|
||||||
char first = name.charAt(0);
|
char first = name.charAt(0);
|
||||||
if( first < '0' || first > '9' )
|
if( first < '0' || first > '9' )
|
||||||
continue;
|
continue;
|
||||||
@ -222,7 +221,8 @@ public class NamingServiceBean extends AddressbookBean
|
|||||||
Properties nsOptions = new Properties();
|
Properties nsOptions = new Properties();
|
||||||
// only blockfile needs this
|
// only blockfile needs this
|
||||||
nsOptions.setProperty("list", getFileName());
|
nsOptions.setProperty("list", getFileName());
|
||||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
if (_context.getBooleanProperty(PROP_PW_ENABLE) ||
|
||||||
|
(serial != null && serial.equals(lastSerial))) {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if (action.equals(_("Add")) || action.equals(_("Replace"))) {
|
if (action.equals(_("Add")) || action.equals(_("Replace"))) {
|
||||||
if(hostname != null && destination != null) {
|
if(hostname != null && destination != null) {
|
||||||
@ -243,7 +243,7 @@ public class NamingServiceBean extends AddressbookBean
|
|||||||
Destination dest = new Destination(destination);
|
Destination dest = new Destination(destination);
|
||||||
if (oldDest != null) {
|
if (oldDest != null) {
|
||||||
nsOptions.putAll(outProperties);
|
nsOptions.putAll(outProperties);
|
||||||
nsOptions.setProperty("m", Long.toString(I2PAppContext.getGlobalContext().clock().now()));
|
nsOptions.setProperty("m", Long.toString(_context.clock().now()));
|
||||||
}
|
}
|
||||||
nsOptions.setProperty("s", _("Manually added via SusiDNS"));
|
nsOptions.setProperty("s", _("Manually added via SusiDNS"));
|
||||||
boolean success = getNamingService().put(host, dest, nsOptions);
|
boolean success = getNamingService().put(host, dest, nsOptions);
|
||||||
@ -308,7 +308,9 @@ public class NamingServiceBean extends AddressbookBean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
|
||||||
|
+ ' ' +
|
||||||
|
_("If the problem persists, verify that you have cookies enabled in your browser.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ import java.io.IOException;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
|
||||||
import net.i2p.util.SecureFileOutputStream;
|
import net.i2p.util.SecureFileOutputStream;
|
||||||
|
|
||||||
public class SubscriptionsBean extends BaseBean
|
public class SubscriptionsBean extends BaseBean
|
||||||
@ -99,7 +98,8 @@ public class SubscriptionsBean extends BaseBean
|
|||||||
public String getMessages() {
|
public String getMessages() {
|
||||||
String message = "";
|
String message = "";
|
||||||
if( action != null ) {
|
if( action != null ) {
|
||||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
if (_context.getBooleanProperty(PROP_PW_ENABLE) ||
|
||||||
|
(serial != null && serial.equals(lastSerial))) {
|
||||||
if (action.equals(_("Save"))) {
|
if (action.equals(_("Save"))) {
|
||||||
save();
|
save();
|
||||||
/*******
|
/*******
|
||||||
@ -115,7 +115,7 @@ public class SubscriptionsBean extends BaseBean
|
|||||||
message = _("Subscriptions saved, updating addressbook from subscription sources now.");
|
message = _("Subscriptions saved, updating addressbook from subscription sources now.");
|
||||||
// + "<img height=\"1\" width=\"1\" alt=\"\" " +
|
// + "<img height=\"1\" width=\"1\" alt=\"\" " +
|
||||||
// "src=\"/addressbook/?wakeup=1&nonce=" + nonce + "\">";
|
// "src=\"/addressbook/?wakeup=1&nonce=" + nonce + "\">";
|
||||||
I2PAppContext.getGlobalContext().namingService().requestUpdate(null);
|
_context.namingService().requestUpdate(null);
|
||||||
} else {
|
} else {
|
||||||
message = _("Subscriptions saved.");
|
message = _("Subscriptions saved.");
|
||||||
}
|
}
|
||||||
@ -125,7 +125,9 @@ public class SubscriptionsBean extends BaseBean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
|
||||||
|
+ ' ' +
|
||||||
|
_("If the problem persists, verify that you have cookies enabled in your browser.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( message.length() > 0 )
|
if( message.length() > 0 )
|
||||||
|
Reference in New Issue
Block a user