In many Posts or Articles.I often saw something like that.
Client-Side :
socket.emit("shhh!Secrets", {
To : "AlexId",
Message : "Hello World!"
})
Server-Side:
socket.on("shhh!Secrets", (Send) => {
io.in(Send.TO).emit("SO...Secrets", Send.Message)
})
Whatever it is socketId , Specific user socketObj or room base .
What If I change Client Source code and change with others room or socketId then my crazy message will saved to others chat timeline...
First Method
Socket.IO is stateful. So this Smart Socket will not forget who you are in every event call.
lets say user want to join room001
So when Joining a socket to a specific Room,Save RoomId To socket.roomId = "room001"
Then use io.in(socket.roomId).emit("SO...Secrets", "message")
Second Method
Never give a change a client directly send message to specific room.
Server-Side:
socket.on("shhh!Secrets", (Send) => {
// Send message only if the user already joined to this Room
if (Send instanceof Object && socket.rooms[Send.TO] === Send.TO)
io.in(Send.TO).emit("SO...Secrets", Send.Message);
})
Mohammed, of course you can change your client code, but you need to know real userId (AlexId in your example), and it is usually uuid, that is not easy to get... So there is very low chance to do that.
By the way, usually in articles use very simple examples and do not mention security aspects, so be careful with it!
Related
I need to configure endpoint on Saga 'Consumer' such as "queue:send-notification" to move from Publish to Send, because I have redundancy on my service (and right now) each email is sent twice.
How can I do that for both test:
x.UsingInMemory((context, cfg) =>
{
cfg.UseInMemoryScheduler(out ISchedulerFactory factory);
_scheduler = factory.GetScheduler();
cfg.UseInMemoryOutbox();
cfg.ConfigureEndpoints(context);
});
And
x.UsingRabbitMq((context, cfg) =>
{
cfg.ConfigureEndpoints(context);
...
cfg.UseMessageScheduler(schedulerEndpoint);
cfg.UseMessageRetry(r => r.Intervals(config.GetSection(RetryIntervalsKey).Get<int[]>()));
cfg.UseInMemoryOutbox();
});
Does the addition of
EndpointConvention.Map<SendNotification>(new Uri("queue:send-notification"));
Is enough??
Well, first, if you have a "redundancy" where you are using the same message type for two separate things, you should resolve that issue. Or if you have two consumers that are sending email notifications in response to the same event, fix that problem.
The use of EndpointConvention is NEVER recommended.
You can, however, use .SendAsync() from the saga, and pass the destination address as the first parameter so that the message is sent instead of using .PublishAsync().
Though it seems like you have system design/architecture issues given the use of the same contract in multiple email delivery services.
So suppose I have created an api for booking hotel room by making a ticket and then I will use the information from the ticket (ex. size, bed etc.) to find available room, but if it could not find any available room I will need to delete this ticket later. So for a better user experience I don't want to suddenly delete the ticket, but I want to change the ticket status to be reject or something else and then delete it after 30second. So here what I have tried.
val ticket = ticketRepostiory
.findById(request.ticketId)
.map { it.copy(status = TicketStatus.REJECT) } // mapping new status
.flatMap { ticketRepostiory.save(it) } // save
.then(Mono.delay(Duration.ofSeconds(30))) // display to user for a 30s.
.flatMap { ticketRepostiory.deleteById(request.ticketId) } // delete it
.block()
notificationService.notify(...etc) // notification service notify status
But I found the problems that this code has blocking the other code for 30s (suppose another user wants to create a new ticket it won't create or save any data to db until 30s.) So how can I delete the data after 30s without blocking other request
So I fixed it now by using .subscribe() method instead of .block()
I am making an application using laravel and twilio that gets feedback about student performance. The logic as follows.
A user, in my case the Student(called resident) logs in and uses a
web page form to send an eval request to a teacher (called
attending). This step starts a session and saves teacher info and
student info.
A random question is picked from a database and saved to the session.
The phone number of the teacher is pulled from a database and the random question is pulled from session and sent to the teacher on SMS using twilio.
The teacher responds with yes, no, or DNS (did not see) via Twilio SMS.
The teacher's response along with the student name, the teacher name and the question asked are saved to a database.
My application works up until step 5. The problem is that a new session is being started when the teacher responds via SMS. So everything after the response is saved to a new session. I can't get access to the original session. I think I need a way to automatically grant the teacher access to the student(ie. user's account). This seems to be a problem with it being a 3rd party application. Can this be done or is there another way to accomplish this?
Below is the code I am using for the response. It is not able to access the session that contains the residentName, the firstQuestion, or the attending_name data. It puts null for those values and uploads null to the database. How do I get access to the initial session in this situation?
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Session;
use Twilio\Rest\Client;
use Twilio\Twiml;
use App\Question;
use App\Answer;
class AskFirstQuestionsController extends Controller
{
public function qOneResponse(Request $request) {
$responderNumber = $request->input('From');
session()->put('responderNumber', $responderNumber);
session()->save();
$responderAnswer = strtolower($request->input('Body'));
$residentName = session::get('residentName');
$firstQuestion = session::get('first_question');
$attending_name = session::get('attending_name');
if (strpos($responderAnswer, 'yes') !== false) {
$answer = new
Answer(['attending'=>$attending_name,'resident_name'=>$residentName,'question_body'
=>$firstQuestion, 'answer_yes'=>1]);
$answer->save();
$smsResponse = "Great! Please help us reinforce this action by providing specific feedback
to the resident about what they did. Thank You for teaching!";
} else if (strpos($responderAnswer, 'no') !== false) {
$answer = new
answer::create(['attending'=>$attending_name,'resident_name'=>$resident_name,'question_body'
=>$firstQuestion, 'answer_no'=>1]);
$answer->save();
$smsResponse = "Ugh, ok...we will work on this. If you feel comfortable, please help us by
providing specific feedback to the resident about what they need to work on. Thank You for
teaching!";
} else if (strpos($responderAnswer, 'dns') !== false) {
$answer = new
answer::create(['attending'=>$attending_name,'resident_name'=>$resident_name,'question_body'
=>$firstQuestion, 'answer_dns'=>1]);
$answer->save();
$smsResponse = "How about trying a different question?";
} else {
$smsResponse = 'Please answer yes, no or dns.';
}
return response($this->respond($smsResponse))->header('Content-Type', 'application/xml');
}
public function respond($smsResponse) {
//get responderNumber and use it below
$responderNumber = session::get('responderNumber');
$response = new Twiml();
$response->message($smsResponse, ['to' => $responderNumber]);
return $response;
}
Do I need to do some type of multiauth approach and somehow grant the teacher automatic access to the student's account (user account)? Or do I have to re-write the logic so that the response-request lifecycle closes and then try to write to the database (maybe it will then use the original session data?)? Or is there a simpler way? Please help. I have been stuck for more than a week.
Twilio developer evangelist here.
I'm not a Laravel developer, but session objects in web application frameworks like this are normally tied to a cookie that either stores the contents of the session or an ID for the session which points to the contents in a database in order to add state to a user's session within a browser.
When Twilio receives an incoming SMS message the webhook that is sent to your server is not connected to the browser session that the user is part of, so you cannot access the same data.
Instead of using the session, you should store this as part of your actual database so that you can look up the details from the database when you receive the SMS.
I am following the Presence Channels section in Laravel docs.
1.Authorizing Presence Channels-I created I function to check is user is authorized to access them.
Broadcast::channel('chat', function ($user) {
...
return user_info;
})
2.Joining Presence Channels-They say I must use Echo's join method. So I did.
Echo.join('chat')
.here((users) => {
console.log('hello',users)
this.users = users;
})
.joining((user) => {
console.log('hey you', user)
this.users.push(user);
})
.leaving((user) => {
this.users.splice(this.users.indexOf(user), 1);
})
Here's the part that confuses me. "The data returned by the authorization callback will be made available to the presence channel event listeners in your JavaScript application". I assume that I suppose to have this Javascript. part and it should be an event listener. I just can't understand where should it be and how I must call it. Have it something to do with a function I use when user logged in?
So, help me understand how to implement these 'presence channel event listeners in your JavaScript application.'
"The data returned by the authorization callback will be made available to the presence channel event listeners in your JavaScript application."
https://laravel.com/docs/5.8/broadcasting#authorizing-presence-channels
This means that the data returned by your authorization callback Broadcast::channel(...) which is $user_info will be available to the joining() and leaving() listeners, or any custom listeners, within your JavaScript application.
The currently defined listeners are waiting to hear another user join or leave the chat channel. Therefore, each user must also fire the corresponding events within their own instance of the application.
// join the channel — trigger joining()
Echo.join('chat');
// leave the channel — trigger leaving()
Echo.leave('chat');
I have an app where one user can invite other users to join an event by push notification. Let's say when creating an event, the user add other users to this event, then save the event to Parse.
So basically I have an array of user_id and I will call a function from cloud code to push notification to those Id, after saving the event.
1)Will the following Cloud code work?
Parse.Cloud.afterSave( "Event", function(request) {
//Get value from Ticket Object
var ids = request.object.get("inviteeIds");
//Set push query
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.containedIn("objectId",ids);
//Send Push message
Parse.Push.send({
where: pushQuery,
data: {
alert: "New Event Added",
sound: "default"
}
},{
success: function(){
response.success('true');
},
error: function (error) {
response.error(error);
}
});
});
I am not sure if the containedIn function exist or not:
pushQuery.containedIn("objectId",ids);
When I search I only find documentation about equalTo function, e.g:
query.equalTo('injuryReports', true);
2) I also read about Channel, but I still not understand how to apply it in my situation. From the documentation:
Devices start by subscribing to one or more channels, and
notifications can later be sent to these subscribers.
In my case how can I create a Channel and then add ids of friends who I want to invite to this Channel?
If possible, I would like to use Cloud Code rather than pushing from mobile device.
1)Will the following Cloud code work?
Why don't you try it and see for yourself, then come back with the errors, if any? Anyway, there's no response in afterSave. It will return a success regardless of what happens in it.
Otherwise it may work. Try running it.
I am not sure if the containedIn function exist or not:
Parse.Query.containedIn
2) I also read about Channel, but I still not understand how to apply it in my situation
Basically you subscribe to a particular channel in the client. Like this (Android)
ParsePush.subscribeInBackground("channelName");
Then in the Cloud
Parse.Push.send({
channels: channelList,
data: {
// etc
}
});
Obviously you'll need to know the channels you want to target.
You can subscribe multiple users to the same channel (for example you can have a dedicated channel for a particular event) or you can have one channel per user (for example you can name it something like channel_<userId> and only subscribe that user to it). Up to you what you need or what you want.
One last thing...
So basically I have an array of user_id
Keep in mind that objects stored in the database have a limited size. If your object gets too big and has too much data, you won't be able to add any more to it.