How to determine timestamp of last API request by user in parse server? - parse-server

Is there a way to determine the timestamp of the last app launch or log the timestamp the last API request from a user on parse server, on the server side without adding code to the client?

To do this without modifying the client, you could think of a request your clients always perform, like a find query and then set a hook on your server like this one from the docs.
Parse.Cloud.beforeFind('MyObject', function(req) {
let query = req.query; // the Parse.Query
let user = req.user; // the user
let triggerName = req.triggerName; // beforeFind
let isMaster = req.master; // if the query is run with masterKey
let isCount = req.count; // if the query is a count operation (available on parse-server 2.4.0 or up)
let logger = req.log; // the logger
let installationId = req.installationId; // The installationId
});
Then just persist the data you want somewhere like the user model and save it.

Related

Ktor Login Session cookie

I am working on a login project using ktor. I am currently using the old method with session
install(Sessions) {
cookie<LoginSession>(
"login_session",
SessionStorageMemory()
){
cookie.path = "/"
cookie.extensions["SameSite"] = "lax"
val secretSignKey = hex("000102030405060708090a0b0c0d0e0f")
transform(SessionTransportTransformerMessageAuthentication(secretSignKey))
}
}
This code is the final one,so if i remove the sessionmanager and secretsignkey, it will show in plain text it's value
The rest is simple, i am routing a get /login to show the form, and a post /validate to validate the data entered by user, then if all is ok i just set the session. The problem is that i can see the session value using inspect element -> application->cookie and i can change it's value being able to login as any user , by just knowing it's id (in the session i am storing the user id). And on the expire column it does not say sesssion. What am I doing wrong?
P.S: I've read the docs for authentication feature but I want to keep this simple idea with sessions.
Use a Ktor session transformer to transform (authenticate or encrypt) the cookie contents.
Example:
// REMEMBER! Change ALL the digits in those hex numbers and store them safely
val secretEncryptKey = hex("00112233445566778899aabbccddeeff")
val secretAuthKey = hex("02030405060708090a0b0c")
cookie<TestUserSession>(cookieName) {
transform(SessionTransportTransformerEncrypt(secretEncryptKey, secretAuthKey))
}

Flutter run multiple http request take much time

I want to ask about increase performance when i do multiple future http request in single page. In case , i want to build a dashboard page. In dashboard, i've 4 endpoints url that return different result in every endpoint and should be shown in dashboard page.
here example code when load data
var client = new http.Client();
Future main() async {
var newProducts = await client.get("${endpoint}/product?type=newly&limit=5");
ProductListResponse newProductResponse = ProductListResponse.fromJson(json.decode(newProducts.body));
var bestSeller = await client.get("${endpoint}/product?type=best-seller&limit=5");
ProductListResponse bestSellerResponse = ProductListResponse.fromJson(json.decode(bestSeller.body));
var outOfStock = await client.get("${endpoint}/product?type=out-of-stock&limit=5");
ProductListResponse outOfStockResponse = ProductListResponse.fromJson(json.decode(outOfStock.body));
var lastRequest = await client.get("${endpoint}/product-request?type=newly&limit=5");
ProductRequestListResponse productRequestResponse = ProductRequestListResponse.fromJson(json.decode(lastRequest.body));
}
every endpoint when i hit manually using postman it takes 200ms for return the result. But when i implement in flutter app, it took almost 2s.
can i improve performance when getting data?
The reason why your code run so slow is that you are making those HTTP requests one by one. Each await will take quite some time.
You can either not use await and implement the logic using callbacks (.then) or you can combine the Futures into one using Future.wait and use await for that combined Future.
Your code will look something like this:
var responses = await Future.wait([
client.get("${endpoint}/product?type=newly&limit=5"),
client.get("${endpoint}/product?type=best-seller&limit=5"),
client.get("${endpoint}/product?type=out-of-stock&limit=5"),
client.get("${endpoint}/product-request?type=newly&limit=5")
]);

Socket.io - Is there a way to save socketid to prevent a new one being generated

After a connection to the socket.io server a socket.id is given for the connection. When the socket connection has not been used after some time a new socket id is generated.
I have read a lot of tutorials that do a "hello world" connection that just gets you connected, but, there is not much literature on messaging peer-to-peer/group. The docs give a 3 line paragraph on rooms/namespaces and every question related to this is just given a link to the same 3 line paragraph.
I understand that you can create and object/array of chats(in this example). For this example, let's say it is an object. That Object looks something like this:
const connections = {
"randomSocketID1": {
recipient: "Mom",
messages: [Array of Objects]
//more information
}
}
I then send a message to randomSocketID1 --> 'Hello'. Then next day I want to send another message to "Mom". Is that socketID going to be the same OR AT LEAST will "randomSocketID1" be updated under the hood, to its updated ID(which sounds improbable)? Is the regeneration of the socketID a product of garbage collection or a socket/engine/websocket protocol?
thanks for any clarification
So I was still unable to find an actual answer to this and by the 0 responses i see that no one knows. So what I have done in order to make sure that user and socket id are maintained is whenever a user enters the component that connects to the socketio server an automatic 'update-user' is emitted and the back end then just finds the user and assigns it the value.
So I have something like this:
chat.component.ts:
ngOnInit(){
this.socket.emit('update-user', 'Ctfrancia');
}
then in the back end:
const users = {};
io.on('connection', socket => {
socket.on('update-user', user => {
if (user in users) users[user] = socket.id;
else users[user] = socket.id
});
});

Getting SessionID During Socket.io Authorization?

I'm trying to get the sessionID from express-session when a new WebSocket connection comes in from a user. I'm able to find the sessionID, I just have a question about its format.
When I make a HTTP request to my messenger page say I get 'X' as a sessionID, if I then made a WebSocket connection I can find the session ID 'AXB', the session ID X is in there, but also surrounded with other information.
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var session = require('express-session');
var io = require('socket.io')(server);
var store = new MemoryStore({
checkPeriod: 86400000
});
app.use(session({
store: store,
secret: 'jpcs-0001080900DRXPXL',
saveUninitialized: false,
resave: true
}));
// ...
app.get('/messenger/:uid', authorizationRedirect, (req, res) => {
console.log(req.sessionID);
// prints "EIVUudPTckmojrkv6FN9Cdb5NAQq5oQU"
// ...
});
io.set('authorization', (data, accept) => {
if (data && data.headers && data.headers.cookie) {
console.log(data.headers.cookie);
cookies_str = data.headers.cookie;
cookies_arr = cookies_str.split(';');
cookies = {};
for (index in cookies_arr) {
cookie = cookies_arr[index].split('=');
key = cookie[0].replace(/ /g,'');
val = cookie[1];
cookies[key] = val;
}
sessionId = cookies['connect.sid'].split('.')[0];
console.log(sessionId);
// prints "s%3AEIVUudPTckmojrkv6FN9Cdb5NAQq5oQU.AQkvP..."
// ...
});
So basically, in io.set('authorization', ...) I get:
s%3AEIVUudPTckmojrkv6FN9Cdb5NAQq5oQU.AQkvPsfoxieH3EAs8laFWN28dr1C%2B9zIT%2BMXtKTRPBg
But in app.get('/...', ...) I get:
EIVUudPTckmojrkv6FN9Cdb5NAQq5oQU
You can notice that the string from socket.io does contain the session id in this format: "s%3A" + sessionID + ".xxxxxxxxxxx..."
So obviously I can get the sessionID from here, but I'm curious why the sessionID is shown like this when I get socket connections? Will it ALWAYS be shown like this regardless of browser, WebSocket implementations, etc? What does the other information contained mean? I mostly want to make sure that this is a reliable way to get the sessionID. Thanks!
I would first like to clarify that io.set('authorization',...) has been deprecated. Here's the updated version Documentation
So obviously I can get the sessionID from here, but I'm curious why the sessionID is shown like this when I get socket connections? Will it ALWAYS be shown like this regardless of browser, WebSocket implementations, etc?
It's not reserved for socket connections at all. That is simply how it is fixed on the browser. So yes, it will always be shown like that.
What does the other information contained mean? I mostly want to make sure that this is a reliable way to get the sessionID. (s%3AEIVUudPTckmojrkv6FN9Cdb5NAQq5oQU.AQkvPsfoxieH3EAs8laFWN28dr1C%2B9zIT%2BMXtKTRPBg)
The first three characters are just encoded, and I believe every sessionID containts that. DecodedURIComponent("s%3A") = "s:"
After that is the sessionID itself (EIVUudPTckmojrkv6FN9Cdb5NAQq5oQU)
Now, after the dot(AQkvPsfoxieH3EAs8laFWN28dr1C%2B9zIT%2BMXtKTRPBg) is the signature portion. That verifies the authenticity of the cookie and is actually given when you sign the cookie. AND yes, I would say it is a trusted and reliable way.

Auth::check() and before('auth') = always sql request for every page?

Am I messing with something or does Laravel conduct sql request to grab data from user table even if all i do on specific page is Auth::check() or have before('auth') filter in router? It can not "get" that user is logged in just from session data (login_82e5d2c56bdd0811318f0cf078b78bfc = user_id etc) without
select * from `users` where `id` = ? limit 1
?
There is some security or other risen to not deal just with session data in case of simple checking of user status (i would prefer to make 1 request per session (not per page) to mysql for user data (or else) and than store it in session, and session set to store in memcached or redis and i am wondering can i get that "out of the box"\without serious changes in Authentication system of framework)?
You can keep it's instance in the container when you check it for the first time
App::before(function($request)
{
App::singleton('myApp', function(){
$app = new stdClass();
if(Auth::check()) {
$app->user = Auth::User();
$app->isLogedin = TRUE;
}
else {
$app->user = false;
$app->isLogedin = false;
}
return $app;
});
$myApp = App::make('myApp');
View::share('myApp', $myApp);
});
Now in every view, you can check like this
#if($myApp->isLogedin)
Hello {{ $myApp->user->user->user_name }}!
#endif
In any controller, you can use it like
$myApp = App::make(myApp); // Get it from the container
// do whatever you want to do
So, you can check logged in or not and also can use Auth::user() object using $myApp->user.