How to remove the data after user has logged out? - security

I was following along the example Lending Library app in the book "Packtpub.Getting.Started.with.Meteor.js". It is running at:
http://matloob.lendlib.meteor.com
It works fine, but when a user logs out when one category is open and its items are being displayed, that category and its items remain on the page while the rest is filtered out. On refreshing the page the remaining category is also filtered out.
The publish function is:
Meteor.publish("Categories", function () {
Meteor.flush(); // I added this so it will flush out the remaining data, but :(
return lists.find({owner: this.userId}, {fields: {Category: 1}});
});

It is hard to point out the exact vulnerability withour seeing more code but this is what I could find out: even if not logged in as a user one can set the session variable current_list to an id to get the corresponding list document:
Session.set("current_list",'ZLREaTCPiC6E7ece3')
So I assume that somewhere in your code you publish the details of a list given its id.
At least this would explain why the list remains even after logging out when a category is selected (which in turn means current_list holds an id).
Possibly publishing the list is done using Deps.autorun since the list is immediately published once the session variable is changed.
Maybe you can find that piece of code and post it or just change it so that it also includes a check whether the user is the owner of that list or category.

Consider using the user-status package to listen for users logging out and doing some cleanup on the server as a result:
https://github.com/mizzao/meteor-user-status
Specfically, you can use the following callback:
UserStatus.on "sessionLogout", (advice) ->
console.log(advice.userId + " with session " + advice.sessionId + " logged out")

Related

Let Alexa ask the user a follow up question (NodeJS)

Background
I have an Intent that fetches some Data from an API. This data contains an array and I am iterating over the first 10 entries of said array and read the results back to the user. However the Array is almost always bigger than 10 entries. I am using Lambda for my backend and NodeJS as my language.
Note that I am just starting out on Alexa and this is my first skill.
What I want to archive is the following
When the user triggers the intent and the first 10 entries have been read to the user Alexa should ask "Do you want to hear the next 10 entries?" or something similar. The user should be able to reply with either yes or no. Then it should read the next entries aka. access the array again.
I am struggling with the Alexa implementation of this dialog.
What I have tried so far: I've stumbled across this post here, however I couldn't get it to work and I didn't find any other examples.
Any help or further pointers are appreciated.
That tutorial gets the concept right, but glosses over a few things.
1: Add the yes and no intents to your model. They're "built in" intents, but you have to add them to the model (and rebuild it).
2: Add your new intent handlers to the list in the .addRequestHandlers(...) function call near the bottom of the base skill template. This is often forgotten and is not mentioned in the tutorial.
3: Use const sessionAttributes = handlerInput.attributesManager.getSessionAttributes(); to get your stored session attributes object and assign it to a variable. Make changes to that object's properties, then save it with handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
You can add any valid property name and the values can be a string, number, boolean, or object literal.
So assume your launch handler greets the customer and immediately reads the first 10 items, then asks if they'd like to hear 10 more. You might store sessionAttributes.num_heard = 10.
Both the YesIntent and LaunchIntent handlers should simply pass a num_heard value to a function that retrieves the next 10 items and feeds it back as a string for Alexa to speak.
You just increment sessionAttributes.num_heard by 10 each time that yes intent runs and then save it with handlerInput.attributesManager.setSessionAttributes(sessionAttributes).
What you need to do is something called "Paging".
Let's imagine that you have a stock of data. each page contains 10 entries.
page 1: 1-10, page 2: 11-20, page 3: 21-30 and so on.
When you fetching your data from DB you can set your limitations, In SQL it's implemented with LIMIT ,. But how you get those values based on the page index?
Well, a simple calculation can help you:
let page = 1 //Your identifier or page index. Managed by your client frontend.
let chunk = 10
let _start = page * chunk - (chunk - 1)
let _end = start + (chunk - 1)
Hope this helped you :)

immutable _id error when performing MongoDB bulkWrite replaceOne on first attempt only

I'm working on a little web application that will crawl and update baseball standings by day and track teams positions (among other things) over time.
I have an API I grab all of this from and a collection in MongoDB that stores all the team data and information for the current day. Right now I just run this manually but eventually it'll be automated to run at like 3am or whenever.
The API supplies a unique ID for each team that never changes. So what I'm doing is I'm taking in the team data from the API. Passing it to a function that then extracts the teams data (there is other data from the response object I don't need), puts it into an object for replacement, and then wherever that team ID exist in the collection its document is replaced in a bulkWite.
async function currentStandings(db,team_standings,callback){
const current_standings = db.collection('current_standings');
let replacePool = [];
for(const single_team of team_standings.data.standing){
let replaceOnePusher = {
replaceOne: {
"filter": {"team_id": single_team.team_id},
"replacement": single_team
}
}
replacePool.push(replaceOnePusher);
}
await current_standings.bulkWrite(replacePool);
callback();
}
However when I execute this code for the first time each day I get an error reading BulkWriteError: After applying the update, the (immutable) field '_id' was found to have been altered to _id: ObjectId('5f26e57b6831761ac840bf1d') (not the same ID every day) and if I look in Compass the data isn't updated. If I immediately run the script again, it goes through successfully without error. Refreshing the data in compass generates the correct data.
Can someone explain to me what is going wrong here? This is actually my first time using MongoDB since I wanted to learn it and this pet project seemed like a good place to start.

How to get a certain (e.g. second or third) mention sent in a message

I've been trying to make a ship command that can either ship the author of the message with a mentioned user, or ship two mentioned users. I can get the 1st mention in a message but I have no idea on how to get the 2nd or even third mention in a message. I tried using:
message.mentions.users.first(2)
splitting the args then slicing them so only the second mention is avalaible, but this gives an "undefined" error when I try to get the username.
Could someone give me a script on exactly how to do it since I can't really get the hang of this
According to the documentation message.mentions.users yields a Collection. So you can just iterate over this collection or convert it to an array and then access the required index:
const userArray = message.mentions.users.array();
console.log(userArray[yourDesiredIndex]);

Permission denied to query class in the Parse Server with JS SDK

I created a class in my Parse Server, using the Parse Dashboard, and then I changed the Class Level Permissions to allow only one user to perform read and write operations in the documents of this class:
The user that is supposed to have access to this class was also created manually through the Parse Dashboard and it looks like this:
However, when I try to query documents from this class, using this user in specific, I keep getting the error message "Permission denied for action find on class Person". This is how my code to login and query the class looks like:
const Person = Parse.Object.extend('Person')
Parse.Object.registerSubclass('Person', Person)
Parse.User.logIn('username', 'password').then(user => {
console.log('E-mail: ' + user.getEmail())
console.log('Created: ' + user.createdAt)
console.log('Current: ' + user.isCurrent())
console.log('Authenticated: ' + user.authenticated())
const query = new Parse.Query(Person)
query.equalTo('name', 'John')
return query.find()
})
I included a bunch of console.log's to check what information about the user is being printed and I confirm that the login seems to complete successfully because the fields email and createdAt match the information that I see in the Parse Dashboard. However, the field authenticated and current both return false, but I don't know why. I was expecting them to return true.
This is the only place in the application that I try to login the Parse Server and perform an operation that is restricted to only one user. Any idea why I'm getting this "Permission denied for action find on class Person" error?
I guess that this is related to security. Generally Parse will not allow a user to get data about any other user, unless you do some actions - e.g. - allow it from the dashboard. But anyway I guess that you have to do it one by one.

How to use the function transaction.retrieve() to get receipt data?

I am developing a transaction workflow capsule, and I use the function transaction.retrieve() to get order data from the platform. But it returns only part of the order data.
MyReceipt is a structure stored the order informations, it is defined like this:
structure (MyReceipt) {
description (order info)
// properties
features { activity}
}
And it is built as a output concept of Commit Action, like this
action (CommitRequest) {
type (Commit)
description ()
collect {
// MyRequest
}
output (MyReceipt)
}
I try to get data like this
transaction.retrieve("bixby.MyCapsule.MyReceipt")
It is supposed to return all the MyReceipt Data. But it return only part of the Receipt data.Is it right to get all the orders? Or is there other ways to get all the receipt data?
And I have found the sample code use it just like this to get the last Receipt data
transaction.retrieve("bixby.MyCapsule.MyReceipt", "ALL", 1)
but it doesn't explain what these two parameter "ALL" and 1 represent for. And I want to get more details about the usage of this function.
Could you plz tell me how to use the function transaction.retrieve() or other function to get all the Receipt historical data, and How can I check out the transaction data for someone when I try to find the cause of the issue.
Copy the answer from dogethis. (Thanks, man! You do the hard work, I took credit)
We have the DOC ready online here
Basically, ALL is the default to get all state of transaction data, and 1 means only one record. The API page was not there before, so thanks for let us know.
I think it's the 1 cause you not get all record, but it does has a limit 20...
Have fun with Bixby!

Resources