trailsjs / sails-auth

Passport-based User Authentication system for sails.js applications. Designed to work well with the sails-permissions module.
https://www.npmjs.org/package/sails-auth
MIT License
265 stars 141 forks source link

Resourceful PubSuB stopped working after installing this on sails 12.1 #130

Closed emudojo closed 8 years ago

emudojo commented 8 years ago

Very easy to replicate.

crete a new project, set up a pretty simple test page

<script type="text/javascript">
            var post, socket;
            document.addEventListener("DOMContentLoaded", function () {

                // socket = io.sails.connect('http://localhost:1337', {
                //  headers: {
                //    'Authorization': 'Basic YWRtaW46YWRtaW4xMjM0'
                //  }
                //});

                io.socket.on('user', function (event) {
                    console.log(event);
                });
                io.socket.get("/user", function (resData, jwres) {
                    if (jwres.statusCode == 403) {
                        console.log("access denied :(")
                    } else {
                        console.log(resData);
                    }

                });

                post = function () {
                    io.socket.post('/user', {username: 'asd', email: "asd@asasd.cm", password: "a12321321sad"}, function (resData) {
                        console.log("Posted Message" + resData);
                    });
                }
            });
        </script>
        <input type="button" value="Create User" onclick="post();"/>

without sails-auth whenever I click on Create User, and while having two clients, I will get the "created" event in socket.on (configuring autoWatch to true)

After installing sails-auth and without changing a single file, the user gets created, but the event is not emitted to the listening socket clients.

is there something I need to do, or this is an actual bug, I enabled some policies, and instantiated the new Sails Constructor with a default user and it works, (if I don't pass the header it fails with the an access denied error)

No custom code, this is just a simple test using the default User Controller and Model that comes bundled with sails-auth and generate api user

emudojo commented 8 years ago

if anyone stumbles upon this problem, the solution was quite simple, but, this is a good candidate for a PR. when sails is using blueprints for actions, the default UserController overrides the blueprint's create method, that has the publishCreate socket method on the newsly created model.

Soluction

Create your own UserController, and then create the following method

create: function (req, res, next) {
        var Model = actionUtil.parseModel(req);

        // Create data object (monolithic combination of all parameters)
        // Omit the blacklisted params (like JSONP callback param, etc.)
        var data = actionUtil.parseValues(req);

        sails.services.passport.protocols.local.register(data, function (err, newInstance) {
            if (err) return next(err);

            if (req._sails.hooks.pubsub) {
                if (req.isSocket) {
                    Model.subscribe(req, newInstance);
                    Model.introduce(newInstance);
                }
                // Make sure data is JSON-serializable before publishing
                var publishData = _.isArray(newInstance) ?
                    _.map(newInstance, function (instance) {
                        return instance.toJSON();
                    }) :
                    newInstance.toJSON();
                Model.publishCreate(publishData, !req.options.mirror && req);
            }
            res.created(newInstance);
        });
    }

This will use passport to create and manage your user, and at the same time will emit the required socket events, that then afterwards you can listen to by using

            io.socket.on('user', function (event) {
                        console.log(event);
                    });