My question is very simple. Is it possible to create a user object without Parse-Server automatically creating a session token?
I have tried this code.
const myNewObject = new Parse.Object('_User');
myNewObject.set('username', 'myCustomKey1Value');
myNewObject.set('password', 'myCustomKey2Value');
let user = await myNewObject.save(null,{ useMasterKey: true });
Not working.
Any solution?
Related
Is it possible to call a cloud function that returns objects without having a current user? The iOS and Android SDKs support anonymous users but I'm asking specifically for JavaScript.
I'd like to allow it so that anyone who visits my web app can read objects without having to sign in. I'm using Back4App.
Yes. You can call a cloud code function no matter the user is logged in or not. Inside the cloud function you can check the user property of the request object to check if the user is either logged in or not. In the case that your user is not logged in and you want to query a class which requires user permission, you can use the useMasterKey option.
Parse.Cloud.define('myFunction', async req => {
const { user, isMaster } = req;
if (isMater) {
// the cloud code function was called using master key
} else if (user) {
// the cloud code function was called by an authenticated user
} else {
// the cloud code function was called without passing master key nor session token - not authenticated user
}
const obj = new Parse.Object('MyClass');
await obj.save(null, { useMasterKey: true }); // No matter if the user is authenticated or not, it bypasses all required permissions - you need to know what you are doing since anyone can fire this function
const query = new Parse.Query('MyClass');
return query.find({ useMasterKey: true }) // No matter if the user is authenticated or not, it bypasses all required permissions - you need to know what you are doing since anyone can fire this function
});
By default, Strapi has a welcome email template and password reset template. For the custom function we are writing, we want to create users without a password (or random password the user doesn't know). Then, when our function is finished, we want to send the user a welcome email (overwriting/disabling the default), with a password reset link. Therefore, we need to call the function/service to reset the password for the user, and receive the URL to send this in the welcome email.
However, currently I cannot find any information regarding the function/service to reset the user password. The only method I now see is to call http://localhost/auth/reset-password with the username or email, but would like to use a service such as strapi.services.user.resetPassword(userID) to get the URL back.
Does this function exists and/or is this possible?
Using Strapi 3.1.2
I have move my original answer here since it was more relevant to the question.
To reset a user password, we have to provide an identifier which is in this case the username. The possible steps are:
Query the user based on the identifier
Generate new hash password based on provided randomly generated value
Update the user password with the newly generated hash-password.
The implementation at a controller can be like this:
module.exports = {
resetPassword: async ctx => {
....
// Provide identifier and newPassword
const params = ctx.request.body;
const identifier = params.identifier
const newPassword = params.newPassword
// Get User based on identifier
const user = await strapi.query('user', 'users permissions').findOne({username: identifier});
// Generate new hash password
const password = await strapi.plugins['users-permissions'].services.user.hashPassword({password: newPassword});
// Update user password
await strapi
.query('user', 'users-permissions')
.update({ id: user.id }, { resetPasswordToken: null, password });
...
}
}
Don't forget to implement isOwner policy, or if the old password can be provided, we can validate the process using isValidPassword
// Validate given old password against user query result password
const isValidPassword = await strapi.plugins['users-permissions'].services.user.validatePassword(old.password, user.password);
I need some help with keystonejs sessions. I'm working on a shopping cart, thus after a customer adds a product to the cart they move onto a check-out page that forces them to sign in as a user. However, when they sign in the session restarts and clears the contents of the cart.
My question: Is there a way to sign in and keep the existing session and then add the user id to the session.
I'm persisting the session to mongodb using connect-mongo.
I have written req.session.cart to add the products to the session
and use
view.on('post', { action: 'login' }, function (next) {
if (!req.body.email || !req.body.password) {
req.flash('error', { detail: 'Please enter your email and password.' });
return next();
}
var onSuccess = function() {
req.flash('success', { detail: 'Great you are now logged in!' });
res.redirect('/checkout');//redirect on success
}
var onFail = function() {
req.flash('error', { detail: 'Input credentials were incorrect, please try again.' });
return next();
}
keystone.session.signin({ email: req.body.email, password: req.body.password }, req, res, onSuccess, onFail);//
to authorize the user.
Regards
As far as I can tell, user signin with Keystone only appends the user property to the request object, and it adds the user's MongoDB id to req.session.userId. It doesn't clear the existing session. How are you currently adding to the Keystone session?
I am wondering that is there any update for this question?
I've digged a little deeper and found that at req.session.reganete() in keystone.session clean the previous session, and the code in keystone looks all good.
I ended up put anonymous user Cart into as an object and at keystone.signin success callback reassign the object back to req.session.cart
[Update after the post]
The session library will clear the session when new session ID issues.
See the discussion here: Request: Option for refreshing the session ID
const currentSession = {}
// 1. have a copy of current session
Object.assign(currentSession, req.session)
// 2. merge the copied session to new session after keystone signin method.
// ...
I don't think you could set that in the session. It is just for users.
Instead I would have a isDraft field on the the Cart List and save the Cart every change of products.
Due to a unprecedented flaw in the way I set up the system to login users, I would like to change passwords for multiple users based off of existing user data. (Users won't care since they are logging in through a one-click gateway).
Is there any way to do this in parse.com?
Create a background job for handling this maintenance:
Parse.Cloud.job('fixUserStuffs', function(request, status) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.each(function(user) {
var newPassword = // do something to generate password.
user.setPassword(newPassword);
return user.save();
}).then(function() {
status.success('All done!');
});
});
Then deploy and run this job ad-hoc through the dashboard. All users will have their passwords changed.
I'm implementing a passport strategy that calls our internal auth service. The internal auth service generates the session ID, so I need to make sure the connect session uses that ID instead of the default generated ID.
Is there a way to do this? Is it possible to provide my own hook function to connect to produce the session id? I can't imagine it's as simple as setting session.id or anything like that, because I don't have control over when or how connect actually creates the session.
Has anyone solved this problem?
This cannot be done with the current implementation of Connect's session middleware, but you can fork the session middleware and change how the session id is generated, namely this line:
https://github.com/senchalabs/connect/blob/master/lib/middleware/session.js#L202
By "fork" I mean copying the file above, changing the assignment of the sessionID and using your new file instead when configuring the session middleware.
UPDATE:
Here's how I would regenerate the session with a custom id (note - this is just an idea, I haven't tested it):
// this is the function you'll be calling in your routes or whatever
req.regenerateSession = function(newSid) {
// keep old session data
var oldSessionData = req.session;
// destroy current session and make a new one with your custom id
store.destroy(req.sessionID, function() {
store.generate(req, newSid);
// copy back the session data
// since you don't want to lose it probably
req.session = oldSessionData;
});
}
// replace the session store generate function to accept a custom sessionID
// https://github.com/senchalabs/connect/blob/master/lib/middleware/session.js#L201
store.generate = function(req, customID) {
req.sessionID = customID || utils.uid(24);
req.session = new Session(req);
req.session.cookie = new Cookie(req, cookie);
}