I'm working on a chat app with Meteor and I'm assuming spam will be an issue so I want to incorporate a Captcha that pops up if you comment too quickly (like more than 3 times in 5 seconds). I have the javascript code below but I have no idea how to do this. Is it possible to have a Captcha just pop up somewhere on the screen? If so, does anybody know how to do this? Here is the code for the chat app part:
Javascript:
// render all of our messages in the ui
Template.chatBox.helpers({
"messages": function() {
return chatCollection.find();
}
});
// get the value for handlerbar helper user
Template.chatMessage.helpers({
"user": function() {
if(this.userId == 'me') {
return this.userId;
} else if(this.userId) {
getUsername(this.userId);
return Session.get('user-' + this.userId);
} else {
return 'anonymous-' + this.subscriptionId;
}
}
});
// when Send Chat clicked at the message to the collection
Template.chatBox.events({
"click #send": function() {
if (Meteor.user() == null) {
alert("You must login to post");
return;
}
$('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
var message = $('#chat-message').val();
chatCollection.insert({
userId: 'me',
message: message
});
$('#chat-message').val('');
//add the message to the stream
chatStream.emit('chat', message);
},
"keypress #chat-message": function(e) {
if (Meteor.user() == null) {
alert("You must login to post");
return;
}
if (e.which == 13) {
$('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
console.log("you pressed enter");
e.preventDefault();
//repeat function from #send click event here
var message = $('#chat-message').val();
chatCollection.insert({
userId: 'me',
message: message
});
$('#chat-message').val('');
//add the message to the stream
chatStream.emit('chat', message);
}
}
});
chatStream.on('chat', function(message) {
chatCollection.insert({
userId: this.userId,
subscriptionId: this.subscriptionId,
message: message
});
});
This sounds like a great idea, but there are some issues with using a 'conditional captcha'. One being that the JavaScript doesn't have any way to persist beyond a page reload besides cookies and localStorage. So a simple reload and clearing of the cookies would defeat it. Not to mention how to handle it on the server, which isn't sure whether it should be expecting a valid captcha input or not.
With that caveat out of the way, you could set a global variable that acts as a 'timer' and just keeps track of the lapse. So replace the last block with:
chatStream.on('chat', function(message) {
//do we already have a timer?
if(typeof window.chatTimer == 'undefined'){
//no, so start one right now
window.chatTimer = new Date().getTime();
}else{
//we already have a timer. Is it 5 seconds old?
var now = new Date().getTime();
if( now - window.chatTimer < 5000) {
alert('Not so fast, tiger.');
return false;
}else{
chatCollection.insert({
userId: this.userId,
subscriptionId: this.subscriptionId,
message: message
});
}
This example uses reCaptcha, minus the custom stuff you would pass in.
Perhaps this has changed recently, but Spambots don't run JavaScript. They are kinda like search engine crawlers that follow links and look for form and textbox elements, and then knit their poison into a POST request to the form's action attribute, bypassing any JavaScript that wants to block it.
In fact, one of the alternatives to a captcha is simply to dynamically generate a hidden input with JavaScript that has an obscure ID/name that the server is waiting for. Spambots won't run this JavaScript, so the checkbox never gets made, so the bot gets rejected without knowing why. Here's more on that.
I have added some code to your code. I never use Meteor so I don't know whether this code is work or not in Meteor. But is test this by creating similes project here
Template.chatBox.events({
"click #send": function() {
if (Meteor.user() == null) {
alert("You must login to post");
return;
}
//Validation
var bot =Check_bots();
if(bot==false)
{
$('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
var message = $('#chat-message').val();
chatCollection.insert({
userId: 'me',
message: message
});
$('#chat-message').val('');
//add the message to the stream
chatStream.emit('chat', message);
}
else
{
// Do whatever you want when a Bot detected
}
},
"keypress #chat-message": function(e) {
if (Meteor.user() == null) {
alert("You must login to post");
return;
}
if (e.which == 13) {
$('#messages').animate({"scrollTop": $('#messages')[0].scrollHeight}, "fast");
console.log("you pressed enter");
e.preventDefault();
//repeat function from #send click event here
var message = $('#chat-message').val();
chatCollection.insert({
userId: 'me',
message: message
});
$('#chat-message').val('');
//add the message to the stream
chatStream.emit('chat', message);
}
}
});
Here is the Validation Codes
<script type="text/javascript">
var lastintime=0;
var defference=0;
var msg_count=0;
function Check_bots()
{
var seconds = new Date().getTime() / 1000;
seconds=parseInt(seconds);
if(lastintime < seconds)
{
defference = seconds -lastintime;
lastintime=seconds;
if(defference<=5 && msg_count>=3)
{
return true;
}
else
{
return false;
}
}
}
</script>
Related
so, as you may know there is an admin-ui library (Idk what to call it) in socket.io.
what I want to do is if a client is kicked, send a message to that client (or have the client detect when it is disconnected)
i have tried:
socket.on('disconnect', function(){
alert('disconnected');
});
but that does nothing...
Found a fix using the socket attribute connected and setting an interval to check if the client is connected to a socket:
// client
let offline_alerted = false;
setInterval(function () {
if (socket.connected === false) {
if (offline_alerted === false) {
alert("Disconnected :(");
offline_alerted = true;
}
} else if (offline_alerted === true) {
alert("Reconnected!");
offline_alerted = false;
}
}, 1000);
So if i fail to login or user does not appear it will prompt a message failed to login or user not found and when that happens i wish the page to reload and go back to the login screen again, i tried with set timeout function but it does not seem to work. Thanks in advance
if (error) {
respond.json(error);
} else {
// If user can be found, result has one record
if (result.length > 0) {
if (input_password == result[0].user_password) {
msg = "1"; // "Success!";
console.log(msg);
} else {
msg = "Login Fail!";
console.log(msg);
}
} else { // If user not found, result has no record
setTimeout(function(){
msg = "User not found!";
window.location.reload(1);
}, 2000);
}
Try just using window.location.reload(true);
It sounds like you need a reference to this.
Why can't I pass "window.location.reload" as an argument to setTimeout?
So before you make the setTimeout save the reload function so it has the proper this.
var fun = window.location.reload(true);
setTimeout(function(){
msg = "User not found!";
fun();
}, 2000);
So Bind it to
$(document).ready(function() {
urlHolder.checkUser = '${checkUser}';
$('#checkUserForm').submit(function() {
checkUser();
});
});
var urlHolder = new Object();
function checkUser() {
$.post(urlHolder.checkUser, {
email : $('#email').val(),
password : $('#password').val(),
}, function(response) {
if (response != null) {
alert('Success! User has been added.');
} else {
alert('Failure! An error has occurred!');
}
});
};
I'm using this code for checking user exist or not. When I used firefox debugger (breakpoint on alert() line ), it worked and server came back a response, but if I didn't put any breakpoint, alert doesn't work, but server came back a response. Note: not only alert() but also window.location.href = "http://stackoverflow.com"; didn't work.
Change the following lines to prevent the form from being submitted:
$('#checkUserForm').submit(function(event) {
event.preventDefault();
checkUser();
});
So i've got a main page where there's 3 buttons - login, register and recover account. I want to disable all those buttons and display a message when geolocation is unavaliable or the user has not allowed the browser to share it's location.
$scope.btnDisabled = false;
$scope.errorMsg = null;
$scope.checkBrowser = function () {
if (navigator.geolocation.getCurrentPosition) {
// let's find out where you are!
console.log("Got your location");
$scope.btnDisabled = false;
} else {
$scope.errorMsg = "Warning. Could not locate your position. Please enable your GPS device.";
//disable the buttons
$scope.btnDisabled = true;
//Show errorMessage
return true
}
//errorMessage visibility is set false
return false;
}
So far i haven't managed to disable the buttons or show errorMessage(except for an alert message).
This is how i got the alert message:
function getPosition() {
console.group("geoloc getPosition");
if (window.navigator) {
console.log("api supported");
navigator.geolocation.getCurrentPosition(success, error);
} else {
console.log("api fallback");
}
console.groupEnd();
}
function success(pos) {
console.log("geoloc pos ", pos);
}
function error(err) {
alert("Geolocation identification failed.");
$scope.btnDisabled = true;
}
Why doesn't the $scope.btnDisable work in error() function?
You should use
navigator.geolocation.getCurrentPosition(
function() {
$scope.btnDisabled=false;
$scope.$apply();
}, function() {
$scope.btnDisabled=true;
$scope.$apply();
}
});
It is verry important to know, that getCurrentPosition will call a callback instead of returning something! See https://developer.mozilla.org/en-US/docs/Web/API/Geolocation.getCurrentPosition
You've also to call $scope.$apply() as you'll disable any angular updates while processing non angular callbacks!
Do so in your 2nd example and the button state should get updated
My server is firing an event to client2 on some request by client1.The fired event is captured correctly by client2.
See the below code:
'experimentService.experimentPermissionChangedByOwner subscribe': function(eventName, event){
if(this.resource.id == event.eventData.resource) {
if (event.eventData.permissionType == "unshare") {
message = this.resource.name +" has been unshared by the owner: "+event.eventData.ownerUsername+". "+messagePart2;
this.openWorkspaceObject({id: event.eventData.dashboardId, namespace: "bjkbb", type: "jhvhhkk" });
}
else {
message = "Owner: "+event.eventData.ownerUsername+" changed permission of "+ this.resource.name +" to "+ event.eventData.permissionType +". ";
if (event.eventData.permissionType == "view") {
message += messagePart2;
}
this.publish("elements.atlas.resource-page-modified", this.resource);
}
this.openDialog({
dialogClass: elements.AlertCollaborators,
message: message
});
}
this.publish("event.ack", {eventId: event.id});
},
The above code is going to create a small dialog box with a message. Now the problem is on refreshing the browser, it again goes into the subscribe function. I dnt know how to handle this? Moroever after putting debug points I saw that it does not go into publish for this method. Then how does the subcribe capture it again??