how can I secure SaveChanges after I added or deleted an entity to breezejs?
var newTodo = todoType.createEntity(initialValues);
manager.addEntity(newTodo);
I want only to add/delete entities to a logged in user. Other users shouldn't be able to add an entity to another user via javascript hack.
Querying only allowed entites is possible via editing EFContextProvider on the server. But how does it work with delete or add?
You can Prevent save Change on server side using
overriding BeforeSaveEntitiesDelegate method of contexProvider.
E.g
_contextProvider.BeforeSaveEntitiesDelegate = BeforeSaveEntities;
private Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> arg)
{
var resultToReturn = new Dictionary<Type, List<EntityInfo>>();
foreach (var type in arg.Keys)
{
var entityName = type.FullName;
var list = arg[type];
if (entityName == "xyz" && list[0].EntityState!="Added")
{
resultToReturn.Add(type, list);
}
}
return arg;
}
This will not save new added entity name "xyz".
Related
I am building an HTML page in Google Apps Script with CRUD functionality. The user can currently add data, edit data, and search data (I am not adding a delete feature). I would like the user to receive the form url link with an ID that when they go BACK to that link, it auto-fills the form with the previously added data.
In my HTML file, I have the following button defined:
document.getElementById("sbtn").addEventListener("click",getTID);
Once a user has entered data, it gets sent to a Google Sheet. The user HAS to enter a unique ID that they've already been provided. Using this ID, they can enter it, hit search, and it runs getTID():
function getTID() { //TID CODE
var transID = document.getElementById("tid").value;
if (transID.length === 36) {
google.script.run.withSuccessHandler(updateAllData).getID(transID);
} else {
alert("Transaction ID is not long enough.\nPlease copy the Transaction ID EXACTLY!\n\nFor Example: https:/workwebsiteconcealedforprivacy/w?txid=36275284-2ed6-4868-97b2-16bc1fde1a08\n\nThe Transaction ID is: 36275284-2ed6-4868-97b2-16bc1fde1a08")
}
}
This takes the ID they gave, references the spreadsheet and then returns values it found by index. Now, I have in my server-side GS file, the following in doGet:
var urlValue = '';
function doGet(e) {
// Test Code
var ss = SpreadsheetApp.openById(id);
var ws = ss.getSheetByName("Options");
var list = ws.getRange(1, 1, ws.getRange("A1").getDataRegion().getLastRow(), 1).getValues();
var htmlListArray = list.map(function (r) { return '<option>' + r[0] + '</option>'; }).join('');
var title = "Please Work";
var vals = JSON.stringify(e);
if ('v' in e.parameter){
urlValue = String(e.parameter['v']);
//return HtmlService.createHtmlOutput(urlValue);
}
return render("page",{list: htmlListArray, title});
and the following:
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function render(file, argsObject) {
var tmp = HtmlService.createTemplateFromFile(file);
if (argsObject) {
var keys = Object.keys(argsObject);
keys.forEach(function (key) {
tmp[key] = argsObject[key]
});
}
return tmp.evaluate();
}
If I uncomment the return HtmlService.createHtmlOutput(urlValue); line, I can see that IF an ID is in the URL, it returns the correct parameter.
My problem is that I cannot get the HTML to read the urlValue variable and autorun getTID() when the user enters the url with the correct parameter. The correct functionality is that IF the parameter is found, it auto populates the HTML form. If it doesn't, it returns the blank form.
There is an error on
return render("page",{list: htmlListArray, title});
On {list: htmlListArray, title} the name of the second property is missing.
To "read the urlValue variable" there are two options:
pass the parameters from the URL using the event object of the doGet function. For this you have two options, create the HtmlService.HtmlOutput object from an html string generated using "vanilla" JavaScript or create it from a HtmlService.HtmlTemplate object.
get the parameters from the URL directly on the client-side code using google.script.url.getLocation .
If you go for the first option, then you should pass someway the urlValue to the render function. In the question code urlValue is a global variable, so you might add the following before the render's return statement.
tmp.urlValue = urlValue;
Then you have to add a scriptlet on the html file to handle this value and "autorun" getTID. Scriptlets is a feature of Templated HTML.
I'm trying to delete entity types through node.js.
My approach is that, the entity name/s that would be deleted will come from a JSON file. I will then list the existing entities on my agent to find the entity id of the entity to be deleted. Then I will send the request to delete it but nothing's getting deleted.
Here's what I got so far:
//entitytodelete is the JSON file containing the entity name
entitytodelete.forEach(function(entityParams) {
entityClient
.listEntityTypes({parent: projectAgentPath})
// look for entity ID of entity type to be deleted
.then((responses) => { const resources = responses[0];
for (let i = 0; i < resources.length; i++) {
const entityTypes = resources[i];
if (entityTypes.displayName === entityParams) {
return entityTypes;
}
}})
.then((entityParams) => {
console.log('The ID of the entity to delete is: ', JSON.stringify(entityParams.name));
const request = {
parent: projectAgentPath,
entityValues : [entityParams.name],
};
return entityClient.batchDeleteEntityTypes(request);
})
As per conversation with #JoshMcD, changing the key entityValues to entityTypeNames worked since method batchDeleteEntityTypes() is intended to delete an entity type.
See sample code:
const request = {
parent: projectAgentPath,
entityTypeNames : [entityParams.name],
};
return entityClient.batchDeleteEntityTypes(request);
I'm searching to get the name of the current view of a record list. Is there a way to do it?
You can use the below script to get the view name from ribbon:
var viewName = '';
if (crmGrid && crmGrid.control) {
viewName = crmGrid.control.get_viewTitle();
}
Reference
Update:
I don't see a supported way to do it. But there are some unsupported solution (may be only way, I haven't tested it personally)
function HideButtonBasedOnViewSelected (selectedCtrl) {
var query = selectedCtrl.get_viewTitle();
if (query == 'Your View Name') {
return false;
}
else
return true;
}
Add Crm parameter, and set parameter value as SelectedControl
To get selected view name need to use some unsupported JavaScript.
Community thread
I have an iphone app created as a multiplication game and saves the following into a class called 'Results'.
PFObject *Results = [PFObject objectWithClassName:#"Result"];
[Results setObject:levelNumberLabel.text forKey:#"LevelNumber"];
[Results saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) etc.
I also have a class called 'currentUser' that stores the following:
PFObject *currentUser = [PFObject objectWithClassName:#"currentUser"];
[currentUser setObject:_firstnameLabel.text forKey:#"SFirstName"];
I want to run a javascript query that 'links' these two tables. I have a point
er set up called 'currentuser' in the currentUser class and a pointer called 'currentResult'.. These hold no value (undefined).
How am I able to merge these classes together? Will it be a case of linking it through the app or using javascript? I'm slightly confused. Here is my javascript code
var Show = Parse.Object.extend("Result");
var query = new Parse.Query(Show);
query.include('currentUser');
query.find({
success: function(shows) {
for(var i = 0; i < shows.length; i++) {
var show = results[i];
var surname = results.get('SSurname');
console.log(i);
var users = show.get('currentUser');
var username = users.get("SFirstName");
$(".success").append(username + " on " + surname + "<br/>");
Any questions/help please let me know.
Any help on the subject would be greatly appreciated
Parse already gives us a User class (PFUser). Consider starting with that one.
Next, create a class that represents the result of play. "Result" (singular) is an okay name for that. It can have string and number attributes as you see fit. (name those starting with lower case, e.g. "levelNumber"). To associate a result with a user, the Result table must also have a pointer attribute to the User, call it "user".
In Objective-C, when its time to save the result of play:
PFUser *user = [PFUser currentUser]; // this is the signed in PFUser
PFObject *result = [PFObject objectWithClassName:#"Result"];
result[#"user"] = user;
result[#"some_other_col_name"] = some_other_value;
[result saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
// ...
}];
In JS, to find the all of the results created by the play of some user:
// if this is called in a cloud function, the request.user will be
// the PFUser on the client that made the request
function resultsForUser(user) {
var query = new Parse.Query("Result");
query.equalTo("user" user);
return query.find().then(function(results) {
// results are the Result objects whose user is the given user
}, function (error) {
});
}
In my chat application project, I am trying to broadcast usernames to all the users whenever a new user is connected to a server. and remove a username whenever the user leaves the server. The below is the code which I have tried by going through tutorials. (please check the file.js file which is not showing the desired output)
Chat.cs (Working) --> Implements "Hub" class of SignalR
public class Chat : Hub
{
/* showing only related content */
static ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>();
public override Task OnDisconnected()
{
var user = _users[Context.ConnectionId]; //user as ConnectionId
User removedUser; //new class object
_users.TryRemove(Context.ConnectionId, out removedUser);
return Clients.All.leave(user, DateTime.Now.ToString()); //dynamic expression
}
public void Joined()
{
User user = new User(Context.ConnectionId, Clients.Caller.username);
_users.TryAdd(user.ConnectionID, user);
Clients.All.joins(user.ConnectionID, user.Name, DateTime.Now); //dynamic expression
}
}
User.cs (Working)
public class User
{
public User(string ConnID, string Username)
{
Name = Username;
ConnectionID = ConnID;
}
public string Name { get; set; }
public string ConnectionID { get; set; }
}
file.js (not working)
var chatUsername = window.prompt("Enter Username:", ""); //username
var chat = $.connection.chat; //connection
//
chat.client.joins = function (ConnectionId, name, Date) {
ConnectionId = 1; /* given value to just test */
name = chatUsername;
};
chat.client.leave = function (user, date) {
user = ""; //making the string empty so that the disconnected user value will be lost.
};
//Here is the connection which calls the "Joined" function of the server (Chat.cs)
What should I write in file.js functions (joins and leave) so that I will get the desired result as I mentioned above. Before asking here, I have gone through this site which is doing the same but including additional javascript files(knockout.js and json) which I dont want to include.(bcos I am new to jquery).
In order to pass UserNames to the client you can take your dictionary and in your joined server side method you could change the SignalR line to be:
Clients.All.joins(_users.Values); //dynamic expression
Then the client version of joins would be:
chat.client.joins = function (users) {
for(var i = users.length - 1; i >= 0; i--) {
alert("User Name: " + users[i].Name + "\nUser Connection ID: " + users[i].ConnectionID);
}
};
Of course you can handle the user information differently than alerting it, but that's the gist of how to handle the data. Lastly, I'd recommend against passing down the connection ID to everyone because a third party could then easily hijack it.