In feathers.js, how do I create an associated object after creating the initial object? - feathersjs

In a feathersjs project, I have two models: user and company. I'm using Sequelize/MySQL.
Every user has one company. Every company belongs to one user.
When a user signs up (is created) I want to create the company object at the same time (with just blank data that can be edited later but with the correct association).
How do I do this with a user after:create hook?

Problem solved. The hook object has access to the app. So the solution:
generate an after:create hook on the user service ("feathers generate hook")
in the hook that is generated, create a company with:
return hook.app.service('companies').create({userId:
hook.result.id}).then(()=> {return hook});

Related

User-created routes ExpressJS

there are websites which create custom sessions for users, giving them unique link to the exact session user has created. E.g. it would like something like https/website.com/session/UniqueRandomID. I guess I understand how custom routes in ExpressJS work, but I'm not quite sure how can I allow a user to create those and later allow other users to connect only to those which have been already created..
Is there a common way of doing it and what may I be missing on the topic?
I tried searching the expressJS documentation.
The term "session" has a rather specific meaning in web site development (it refers to data associated with a given browser's visit to a site and is used for things like tracking the logged in state of a user) so I'll use the term "project" in this answer.
When the user creates a project, store all the information about that project in a database. Include, as part of this information an identifier. You probably want this to be a GUID or similar (there are libraries which will generates these for you) rather than something sequential (like an automatically generated database primary key).
The first page of the React Guide explains routing. Create a route that uses a route parameter for the project ID.
Use that project ID to get the data about the project from your database.
If there isn't any for that ID, return an error.
app.get('/projects/:projectId', async (req, res) => {
const projectData = await getProjectData(req.params.projectId);
if (projectData) {
return res.render('projectView', projectData);
}
res.sendStatus(404);
})

Foundry Workshop - Prevent duplicate data entry

I am building a Workshop App which will be used for data entry by a large number of operational staff members (> 200).
I would like to implement the following set-up:
The staff will enter the data on existing Ontology Objects. To facilitate this, I embedded a Foundry Form into the Object View, and set-up a corresponding write-back data set.
The Ontology Objects in question will be displayed in an Object Table in Workshop.
The staff member will select an Object from the Object Table.
The selected Object will be opened in an Object View.
The staff member will enter data on the Object View (Foundry Form being displayed here).
I need to make sure that no concurrent data entry can/will happen. How can I achieve this?
I am thinking about removing any Object which is opened in the Object View from the Object Table, but I am not sure if this is the best solution to the problem or how to achieve the removal from the table.
I am assuming that this must be a common problem and there would be a Design Pattern/Standard Functionality to solve this.
You'll have the best behavior here if you replace your Foundry Form with Foundry Actions. These actions are defined in the Ontology Management App and provide a more robust security model for managing object edits and are more tightly integrated into the various object-layer tools in Foundry.
Then in your Object View, rather than using the Foundry Forms widget, choose to create a new "Workshop-backed" Object View tab - this option is under the dropdown next to the New Tab button - and within the Workshop module use the Inline Action Form to embed the action form that you've configured in the Ontology Management App, supplying the variable representing the current object as the default for the object parameter in the Action.
With regards to simultaneous edits, in Actions, when the form is populated (i.e. when that tab is opened), the version of the underlying object(s) are registered. When the edit request is submitted, the current version of the object is checked, and if the version is different (i.e. there have been edits applied since the form was loaded) the user will be presented with message to the effect that the object has been updated and the edits will not be applied.
This protects against the case of a user overwriting a near-simultaneous edit without reviewing the changes first and does so at the writeback layer, rather than with logic in your application front-end.
There is not currently an approach to reflect real-time user interaction between two Workshop sessions. For instance, there is no way for the session of User A to "know" that User B has opened Object X in their session and is making a change.
If you wanted to do something for a bit of convenience or display signaling, you could create a small object type related to your main object - something like "Edit Lock" that looks like:
| id | primary_object_id | user_id | timestamp | timeout
And then in your Workshop app, there's a button above the table that says "Edit Selected Object".
When you click this button, you trigger an Action to create a new "edit lock" object populated with the current user and the current timestamp and say a timeout of 15 minutes from now.
Then in the object view for the primary object in question, on the same tab where you have the edit form embedded, you can create a variable that gets the edit locks associated with that object via a search around and use a Function to create a boolean variable if there is an "active" edit lock. And use this to conditionally show a banner to the user or otherwise give them a visual indication that another user has indicated they're making changes.
This won't push to the other session, and it'd be just for display purposes, the real protection still comes from the underlying object versioning that Actions enforces, but it might be a nice user affordance to layer on top if you really expect to commonly run into this situation.

NATS - just one subscriber to take action for published event in a microservicearchitecture

I'm new to NATS and have read all the examples for:
https://nats.io/documentation/concepts/nats-messaging/
I'm in Microservciearchitecture where in microservice-Y (MSY) need to store some information published from other microservice-X (MSX) I have 2-10 instances of MSY so when changes are made in MSX and MSX-instance publishes event I want that only 1 instance of MSY should save information so not all of them save the same data.
I have read Request-Repy:
https://nats.io/documentation/concepts/nats-req-rep/
but there seems that all of instances receives message (and will handle it) even if it is point-to-point and reply is handled just for the one instance that is quickest to reply
Is this correct or have I missunderstood example?
If I only need that 1 instance of MSY should handle given message (store data in db) what can I do to acheve this?
Use queue groups. If you have multiple subscriptions on the same subject with the same queue group, only one of the members of the group will receive the message.
Check this out: https://nats.io/documentation/concepts/nats-queueing/

Spring Security Authenticates User with old credentials until Web App Restart

Hi there I am developing a web app and I am using Spring Security. In the app the user can change his/her details (username, password and some other fields). I am using a custom User Details Class for this and my Spring Security configuration is the default (keep in mind no cache method is declared, so I suppose NullUserCache is used). All the user records come from DataBase using JDBC Connector (MySQL).
Now when a user changes his/her info or/and username-password those changes update the corresponding columns in DataBase. So now the DB is updated. Because I have not implemented setters in my Custom User Details Class, I force the user to logout log out automatically. But now he/she can login using both the new username and the old one.
Suppose now that the user changed something on the other fields (for example if the age was changed from 20 to 21). When user logins using the new username I can see 21. If user logins using the old username I can see 20!.
I guess Spring Security now creates a new User (during login) which didn't exist and the old one is never removed!
So after reading many posts in the web and trying the corresponding solutions I 'm still unable to fix that.
What I have used (in the controller that is responsible for account editing):
if (authenticate != null){
new SecurityContextLogoutHandler().logout(request, response, authenticate);
}
SecurityContextHolder.getContext().setAuthentication(null);
SecurityContextHolder.clearContext();
What I understand and believe is that Spring Security holds somewhere (I thought User Cache) the username, maybe along with the password and now it sees the old username as a different User. The only way to prevent this from happening is to restart the app. After restarting the user only logins using the new username.
Is there any way I can remove that "user"-username? Any suggestion would be usefull, I am really confused and the only case close to mine was this but his problem was with the oracle connector using connection cache..
UPDATE problem tracked down to a problem inside loadbyusername method..read more on the 14th comment below :)
Happy coding!
I finally found the source of that problem..black hole closed. Credits #Jebil and #Robin Winch for their help!
Well everything worked as it should except the fact that the HashMap on the rensposible for the login DAO, was never cleared..so after every successful login attempt the HashMap returned was appended and so after every username update, it contained both old and new values..solution was simple..before accessing the DB HashMap should be cleared!
Happy dividing by 0 :P

Cake ACLs with Groups and Users added to Projects

I'm currently working on a platform which is planned to coordinate the communication with customers in future. Users can be added to projects and have certain rights. Therefore users are assigned to different user roles (admin/manager/member/viewer). Admins can view all projects and are allowed to add other users to a project. If a user (e.g. role:member) is added to a project, he will have certain rights (depending on the role), if not, he is not allowed to access the project at all.
I'm using Cake's ACL Component and everything is working great, when i disregard if a user is added to a project or not. The only solution I can think of, is not to grant rights on the group-level, but on the user-level when an admin adds an user to the project.
Is there an easier way to solve this issue? Otherwise I'm afraid that the code would become totally confusing.
There is a another way (I don't really know if easier, depends on your point of view). The ACL component only helps you to create roles, but you need a role and project-access management, right?
What I do in this cases:
Create a Project_Permission table in your database (give it a better name, I'm lacking imagination). Depending on your project, create the associations: a user can be related to many projects and a project can have many users accesing it. If you are following the cake conventions (and your tables are named users and projects) and it doesn't interfere with what you already have, the table should be
PROJECTS_USERS
id
project_id
user_id
created and modified //if you want to
Create appropriate actions where the admin (or other type if users, that's up to you)
can add users to projects and save that many-to-many association in
the previously created table.
Since the authorization for the project does not come from the ACL component, you have to create an "authorization" function yourself. I recommend putting this in the beforeFilter() function of the AppController (if you don't have an AppController, you'll have to do it in every controller you want this to work). In this function, check if the logged user is in the existing table and has an association with the project. Something like:
function beforeFilter() {
//let's assume you have the project id somewhere, in a global variable like $this->_projectID
$user = $this->Session->read('Auth.User.id');
$project = $this->Project->find('first', array('conditions'=>array('id'=>$this->_projectID, 'User.id'=>$user)
if (count($project) > 0) {
//the user has permission to see the project
} else {
//he doesn't
}
}
It's difficult to give an actual code because I'm not sure of your model associations nor where do you want the code or if you have the variables needed for this available everywhere, but I hope you get the idea. After that it's just a matter of how you want to handle the restriction of access (normally a flash message and redirection is involved).
I hope this is clear enough :S