adding data based on users login credentials (Lightswitch HTML) - javascript

I've been doing some research into how I can add data based on the login credentials. as an example scenario lets say I want a user to login to the application and then based on there login, add there hours they have done for that day, so like a timesheet application.
I don't want the user that is logged in to see any other names other
than there own.
the browse screen would show only there times they have submitted
rather than everyones aswell.
when using the insert call method in (_customnameDataService.cs) you can add in a username by associating a field within a table like below:
entity.Username = Application.User.Name
so if this is possible there must be a way of calling this in JavaScript when logging in so any help or pointers would be great help. Adding a DataItem and displaying the username would be most preferable. (using edit render code) then from this I can pass it through the hierarchy and display only the information associated with the logged in user.

follow these steps to achieve the above question:
Google GetUserName.ashx to get the code for this file to add to your
Lightswitch HTML Project.
copy the below function into the javascript file (in my case a Browse screen for my users)
function CallGetUserName(operation) {
$.ajax({
type: 'post',
data: {},
url: '../web/GetUserName.ashx',
success: operation.code(function AjaxSuccess(AjaxResult) {
operation.complete(AjaxResult);
})
});
}
For the users that can login in and access the Lightswitch Application, the user information must be stored somewhere, in my case "tbl_Users". This table has a row called username. Using the below code this enables an administrator or someone high up in the hierarchy to access all the users, and also the specific user referenced in the table to access themselves.
myapp.BrowseUsers.username_postRender = function (element,
contentItem) {
msls.promiseOperation(CallGetUserName).then(function PromiseSuccess(PromiseResult) {
if (PromiseResult == 'TestUser' || PromiseResult == 'administrator') {
} else {
contentItem.value = PromiseResult;
}
});
};
What is actually happening?
The function is calling the GetUserName.ashx file, which in turn retrieves the current user logged in. (from the aspnet_Users table which is automatically created) I have used a foreign key to associated my table (tbl_Users) and aspnet_Users together.
in the debug or release environment if you were to add a data item (string) and display this information, it would return ("TestUser")
myapp.BrowseUsers.displayUsername_postRender = function (element,
contentItem) {
msls.promiseOperation(CallGetUserName).then(function PromiseSuccess(PromiseResult)
{
element.innerText = PromiseResult;
}); };

Related

Not able to get the record GUID in JavaScript code on save of Quick Create form

I'm facing a problem on the Save event of the Quick Create form for the Case entity. On Save event, I'm not able to get the record GUID in JavaScript code.
Our requirement is when the user clicks on Save button on Quick Create form of the Case, we would like to redirect the user to the newly created case record.
We have attached below Javascript function on save event of Quick Create form. This code works well on one of the 30-days trial instance, but it doesn't work well on the client development CRM instance.
setTimeout(function () {
var formContext = executionContext.getFormContext();
var caseId = formContext.data.entity.getId();
caseId = caseId.replace("{", "").replace("}", "");
var entityFormOptions = {};
entityFormOptions["entityName"] = "incident";
entityFormOptions["entityId"] = caseId;
Xrm.Navigation.openForm(entityFormOptions).then(
function (success) {
console.log(success);
},
function (error) {
console.log(error);
});
}, 1000);
Quick create form purpose is flyout data entry without going away from current form/record. The same QC form is being opened from different places like Dashboard, Subgrid, Main navigation too bar, Lookup, etc. and allow user to continue the ongoing stuff. Out of all these places - only from the Main navigation, after the save - system will prompt with a toast to navigate to that record or option to create another record. This is by design.
If you want to navigate to that record irrespective of the origin, you can try some scripts like yours but you are going to break the OOB pipeline flow. You may do some unsupported but it’s not recommended. I never tried it but you can add a function from onSave event, using eventArgs.preventDefault we can stop the OOB save, then open the Full Main form by prepopulating values from QC to Main form, then save it on form load.
Instead of all this pain, why not you open the Main form itself. :)

Firebase specific node read and write

I implemented on a website a form to create firebase users and add a node in the firebase database for the user based on a selected State in the form.
So for example, if the user chooses 'Hawaii' in the form and then create the account, the account information will be stored in "Hawaii/id" in the firebase db.
// JSON structure
{
"Hawaii": {
"place1Id": {
//infos
},
"place2Id": {
//infos
}
},
"New York": {
"place1Id": {
//infos
},
"place2Id": {
//infos
}
}
}
My problem is how to make sure that later on when the user will add information to his account, with provided credentials from the previous account creation, this information will be stored in the correct node (Hawaii for example)
I have tried to make a comparison between current user id and keys from States nodes but my database is quite large (and will become larger) so it is taking up to 10 seconds for the code to determine in which node of the database the user is.
And the same process has to occur on each page so it is not the good solution.
var placesRef = firebase.database().ref();
placesRef.once("value", function(snpashot) {
if (snpashot.child("Hawaii").hasChild(user.uid)) {
console.log("Place is in Hawaii");
activiteRef = firebase.database().ref().child("Hawaii").child(user.uid);
}});
Can you please help me figure this out?
Thanks!
If you're keying on uid, you don't need to do anything more than the line you already have:
activityRef = firebase.database().ref().child("Hawaii").child(user.uid);
This is the direct reference to the node you want (if I'm understanding you correctly). You can read the data:
activityRef.once('value').then(snap => console.log(snap.exists, snap.val());
Which will be null if the user has never written there, but will contain data otherwise. You can also perform other operations like update() to change the data at this location.
There's no need to perform the top level query to check if the node already exists -- you can just read it directly.

How to query firebase for many to many relationship?

It is my first time developing a SPA, and I am not using JS frameworks like React, Vue or Angular. My project just uses the firebase sdk and jquery to access the DOM elements.
In my app, the users can be associated with projects. Since that, I have a user-projects and project-users paths to represent that relationship.
When a user logs in my app I request users/uid to get the user data. After that I have to fetch the projects associated with the user. I will take the ids of the associated projects to finally request the data of each project.
I'm trying to use promises as described here, but I get nothing in the console.
function loadUserProjects() {
// Authenticated user
var user = firebase.auth().currentUser;
// General reference to the real time db
var ref = firebase.database().ref();
// Request the user data
ref.child('users/'+user.uid).on('value').then(function(snapshot) {
var user_data = snapshot.val(); console.log(user_data);
// Global variable to store the id of the selected project
project_selected_key = user_data.project_selected;
// Get the list of associated projects
return ref.child('user-projects/'+user.uid).on('value').then(function(snapshot) {
console.log(snapshot);
return snapshot;
});
}).then(function (projectsSnapshot) {
console.log(projectsSnapshot);
// List associated projects
var project_options = '';
projectsSnapshot.forEach(function (e) {
project_options += '<option value="'+e.key+'">'+e.val()+'</option>';
});
if (! project_options) {
project_options = '<option disabled selected value>- Ningún proyecto -</option>';
}
$('#project_selected').html(project_options);
}, function(error) {
// Something went wrong.
console.error(error);
});
}
I know that I have to use one additional request, because at this point the <select>will be populated with truevalues (the additional request have to query the full data of each project). But I am not getting messages in the console.
Thanks in advance.
After that, I need to define different levels of privilege in each project, and associate a level when a project is assigned to a specific user. Initially I was very excited about the real time, but it seems that firebase is getting more complicated than I supposed.
A Firebase on() listener can respond to multiple events. A promise can only resolve once, that's why it's only available when you use Firebase's once() operation.
return ref.child('user-projects/'+user.uid).once('value');

Meteor - Allow multiple users to edit a post

I'm not able to use the node server debugger so I'm posting here to see if I can get a nudge in the right direction.
I am trying to allow multiple users to edit documents created by any of the users within their specific company. My code is below. Any help would be appreciated.
(Server)
ComponentsCollection.allow({
// Passing in the user object (has profile object {company: "1234"}
// Passing in document (has companyId field that is equal to "1234"
update: function(userObject, components) {
return ownsDocument(userObject, components);
}
});
(Server)
// check to ensure user editing document created/owned by the company
ownsDocument = function(userObject, doc) {
return userObject.profile.company === doc.companyId;
}
The error I'm getting is: Exception while invoking method '/components/update' TypeError: Cannot read property 'company' of undefined
I'm trying to be as secure as possible, though am doing some checks before presenting any data to the user, so I'm not sure if this additional check is necessary. Any advice on security for allowing multiple users to edit documents created by the company would be awesome. Thanks in advance. -Chris
Update (solution):
// check that the userId specified owns the documents
ownsDocument = function(userId, doc) {
// Gets the user form the userId being passed in
var userObject = Meteor.users.findOne(userId);
// Checking if the user is associated with the company that created the document being modified
// Returns true/false respectively
return doc.companyId === userObject.profile.companyId;
}
Looking at the docs, it looks like the first argument to the allow/deny functions is a user ID, not a user document. So you'll have to do Meteor.users.findOne(userId) to get to the document first.
Do keep in mind that users can write to their own profile subdocument, so if you don't disable that, users will be able to change their own company, allowing them to edit any post. You should move company outside of profile.
(If you can't use a proper debugger, old-fashioned console.log still works. Adding console.log(userObject) to ownsDocument probably would have revealed the solution.)

Azure Mobile Services - Alter User model on Insert script

I have a reservation model and a user model. In the insert script for my reservation model, I have the following:
function insert(item, user, request) {
response.send(200, 'test');
item.organizationid = user.organizationid;
if (user.hourstoreserve <= (item.endtime - item.starttime)) {
request.respond(400, 'You do not have the necessary hours available to make this reservation');
} else if (user.complaints >= user.complaintsallowed) {
request.respond(400, 'You are over your maximum number of allowed complaints this month.');
} else {
user.hourstoreserve = (user.hourstoreserve - (item.endtime - item.starttime));
request.execute();
};
};
I need to make sure that item, which should be my new reservation that I am inserting, gets an organizationid from my user. I also then want to make sure the user has it's hourstoreserve validated, and if the reservation is made the user's hourstoreserve should be lowered.
It seems like this script isn't being executed at all. The first response.send(200, 'test'); does not send a response.
I am calling this insert script from my custom api similar to the following:
var reservations = request.service.tables.getTable("reservations");
reservations.insert(newReservation);
The custom API call works and inserts the reservation as it should, it just doesn't seem to execute my insert script.
Any help is appreciated.
When you invoke the CRUD operations of the tables from the service itself (i.e., in the code of a custom API, scheduler or another table), the table scripts are not executed. There's an open feature request to have this feature added to the backend, please upvote it if you think it will help you.
Another problem which I see in your code - the user object which is passed to the insert script isn't an item from your user model; instead, it's the information about the logged in user to the service (i.e., in the client side, after calling one of the login operations, that will be the user information it will have). That object doesn't have any properties about organization id, hourstoreserve, etc. If you need to get that information, you'll need to query your users table and working with it directly.

Categories

Resources