Sails publish(Update) system does not propagate to associations - websocket

We are building a realtime webapp on sails 0.10.5. We have a lot of models linked through associations. For example we have a User model and a Post model, where a post always has one user.
The populate makes sure that when fetching a user, we also get the posts. We tell the (websocket) client about updates using the subscribe and watch model methods in our sails controllers.
However whenever a websocket client is watching both the User model (watch and subscribed to all users) and the Post model (watch). And a new Post gets created (via another socket for example) our client only receives a new event for Post, while the User changed as well (indirectly through an association).
How can we make sure our clients get those updates as well? Basically we need a way to sync the results of any populated model to our clients.

I'm not sure if this is the best way to do that but does the work:
Basically, anytime you update a Post you can publish a User "update" event.
// Post.js
module.exports = {
attributes: {
title: 'string',
owner:{
model:'user'
}
},
afterUpdate: function(post, cb){
User.publishUpdate(post.owner, {/* props you want to send */});
cb();
}
};

Related

Using EventHandler to warn a user that their session is ending

I have been trying to warn the user that their session is about to end using dialogflow CX. But I can't get it to respond to me, without the user making a request first.
Is there any way to do this without the user making a request first?
For your use case, if you’ve integrated your agent to your custom application, you can do your own implementation to create a timer that tracks the session time of the user and display a warning on your custom application that the user’s session is ending soon. This approach must be done on your custom application’s side and does not require the use of Dialogflow.
Alternatively, you can use the timer that tracks the session time of the user on your custom application to send a detectIntent request containing the current session ID of the user to your agent to trigger an event. This lets your agent send a response to the user within the same session without having the user to first send a request.
Inside your flow, select the page you want to add a custom event to. Then, click the “Add route type” button to add the Event handlers if not yet added.
Click on the + sign beside “event handlers” field and select any event.
Tick the check box beside “Use custom event”.
Add the name of the custom event you want to use.
Here’s a sample detectIntent request that triggers a custom event using REST API:
Sample URL for detect intent API:
POST
https://dialogflow.googleapis.com/v3beta1/projects/project-id/locations/us/agents/agent-id/sessions/session-id:detectIntent
Make the following replacements for the URL:
project-id: your GCP project ID
agent-id: your agent ID
session-id: your session ID
Sample JSON Request Body should look like this:
{
"queryInput": {
"event": {
"event": "custom-event-name" // custom event to be triggered
},
"languageCode": "en"
},
"queryParams": {
"timeZone": "America/Los_Angeles"
}
}
You can refer below for more information on:
Sessions
Custom events
For more samples on detect intent calls, please refer to this link.
To integrate your agent with your own application, you can use Dialogflow CX’s Client Libraries, Rest API, or RPC API.

Mysterious users in my database that didn't come from my registration process

I have a Laravel-5.5 application in development with a live test application exposed on Google App Engine. My registration process includes the standard Auth registration from Laravel. The RegisterController then redirects to a profile page if there isn't one for the user already.
public function redirectTo()
{
if (!Auth::user()->profile)
{
return '/profile';
}
else
{
return $this->redirectTo;
}
}
The profile controller creates a new userprofile record for the user automatically as the page loads.
$(document).ready(function ()
{
...
getProfileData(profileId);
...
});
getProfileData() posts to the controller. If ProfileId is empty, the controller creates a new record and sends a verification email to the registered address.
How can a user be created without then being redirected and a profile being created?
Users are being created on the live site without profiles or sent verification emails. The user_agent in the session records for these users appear to be real.
Any ideas about how these users are being created and how to stop it would be most helpful.
I believe that Laravel is actively being attacked by actors that are seeking sites with poor security practices. It starts with visiting the site and getting an active session, Then harvesting the sessions csrf-token and using the token in a non site generated post (crawler?) to the standard Laravel registration route.
Since my site has a two part registration that generates a profile and the profile needs to be verified by a human before access is granted, registering and then ignoring the response's redirect to the profile page gets the partially completed registration.
To stop the resulting database clutter in the users table I changed both the standard authentication routes and the expected fields that are returned from the registration form.
Since these changes I have had no half registered users show up in the database. I'll update this answer if I ever see more of this activity.

Apollo GitHunt-React: updateCommentsQuery?

I'm working on Apollo pub-sub using examples from GitHunt-React and GitHunt-API. My subscription resolver is successfully firing when a new record is added to the database it is watching. Now I need to connect my client to the results being sent by the pub-sub resolver.
In GitHunt-React, CommentsPage.js, I see this:
subscribe(repoName, updateCommentsQuery) {
[.....]
}
Where is updateCommentsQuery declared and how is it being passed to subscribe?
It's passed in as an argument. This is because subscribing and re-subscribing currently has to happen manually when props change: https://github.com/apollostack/GitHunt-React/blob/9b2cc222ef18ee4f89fd4bae3da0a4c0f61b2bb8/ui/routes/CommentsPage.js#L29
But ideally in future Apollo Client releases it will be easier to manage the subscription lifecycle. It's still a pretty experimental feature and we're figuring out the best way to do it.

Where does request.user come from in Parse Server

I'm trying to port my Parse.com app to Parse server.
According to the Parse migration guide, Parse.User.current() can no longer be used and instead you should fetch the current user via 'request.user'.
However, request.user is always undefined for me.
For example, when I successfully login a user and then redirect to another path (/mypath), the incoming request at mypath does not contain a user object.
Parse.User.logIn(username, password, {
success: function(user) {
res.redirect('/mypath');
}
})
// Index of the /mypath controller
exports.index = function(request, response) {
// request.user is undefined here
}
How do I work with the active user after I logged in sucessfully?
I think I figured it out.
When working in Cloud Code there is no magic request.user. Rather when logging in you need to manually store the user info in the current session. In the Parse.com days this would've been managed by the parse-express-cookie-session middleware. This is explained in the cloud code guide. With Parse-Server you can insert your own middleware to manage the user as is described here.
However, the request.user will be available when receiving requests from a client SDK using an authenticated user.

How to avoid 'Choose Account' screen with Google Calendar API?

Our app is importing the next 1000 events from a user's Google calendar API. We ran into the problem where nginx would timeout. To get around this I'm putting the pagination data into a session variable and making separate HTTP requests to the API. This works except for one problem: every time we make a new HTTP request the API asks the user to choose which account they want to use (one user with multiple gmail accounts). I would have thought that the pagination data would include account selection but this is apparently not the case. How can I programmatically select the email account within the HTTP request?
You can store it once
public static void setmCredential(GoogleAccountCredential _mCredential) {
mCredential = _mCredential;
mService = new com.google.api.services.calendar.Calendar.Builder(
transport, jsonFactory, mCredential)
.setApplicationName("YourApplicationName")
.build();
}
And then when caliing pass it like this
new MakeRequestTask(AccountCredential.mService).execute();

Resources