Mo Plugins Mo Problems

NodeBB Development
  • Hello again. Another plugin, another case of me banging my head against a wall. 😄

    I'm building a Soundcloud oAuth plugin, however am running into issues on the return journey from Soundcloud.

    My site 500s at

    Internal error.
    Oops! Looks like something went wrong!
    Cannot read property '0' of undefined

    I've gone through the plugin, but can't really see what the issue could be.

    I'm so close, I can almost taste success. This is the repo if anyone would like to spot my obvious mistake here.

    To add: Soundcloud doesn't supply an email address via oAuth. So I'm not sure how to get around that either. 🙂

  • @a_5mith I was getting the same error while trying to make the linkedin sso. It ended up being the email portion of the code.

    I'm not sure exactly where your error is, but I'm assuming you would be using could from one of the other sso plugins to make things easier. If so, in your getStrategy expression try logging the callback of the callback.

    For example, in the google sso plugin here is the getStrategy code:

    Google.getStrategy = function(strategies, callback) {
    		meta.settings.get('sso-google', function(err, settings) {
    			if (!err && settings['id'] && settings['secret']) {
    				passport.use(new passportGoogle({
    					clientID: settings['id'],
    					clientSecret: settings['secret'],
    					callbackURL: nconf.get('url') + '/auth/google/callback'
    				}, function(accessToken, refreshToken, profile, done) {
    					Google.login(, profile.displayName, profile.emails[0].value, function(err, user) {
                           // You want to log the 'user' variable here to see what's getting returned
                          // console.log(user);
    						if (err) {							return done(err);
    						done(null, user);
    					name: 'google',
    					url: '/auth/google',
    					callbackURL: '/auth/google/callback',
    					icon: 'fa-google-plus-square',
    					scope: ''
    			callback(null, strategies);

    This should get you info as to what is returning undefined, but if you look at the code above there is a call to: profile.emails[0].value which correlates to the error message you are getting.

    EDIT: Sorry, actually you want to log above where I want to see what's getting sent as the 'profile'

    function(accessToken, refreshToken, profile, done) { // log the profile here

  • @a_5mith Also, I found this on stackoverflow...same reason I can't use the twitter sso auth...

    Sounds like SoundCloud doesn't provide the email. If that doesn't matter to you then you can probably just delete the profile.emails[0].value part of the code and it should work. Having said that, you will get new users being created on your nodebb if their soundcloud username and nodebb username are different. This is what happens with the twitter sso auth.

    Edit: Si!

  • @mootzville thanks, soundcloud doesn't return, so it's going to be a twitter esque approach to that, I'll do a bit of logging and see what's returned.

    Edit: I got ninjad.

  • Right, progress, I'm now getting soundcloudId is not defined. It's returning all the relevant data though, which is good.

    Trouble is soundcloudId is mentioned quite a bit at various points towards actually creating the data, so I don't really know at what point I should be looking at. 😆

    If anyone wants to try it and see what they can figure out, it's currently still enabled on my site:

  • It works. 😆 I've built an oAuth plugin.


    The avatar bit don't work yet, but I've got an account.

  • Aw, David Tennant! I just finished watching The Fall of Pompeii

Suggested Topics

  • 0 Votes
    4 Posts

    @julian found the issue and created a PR here

    Thank you for sharing the repo 🙂

  • 1 Votes
    9 Posts

    @khalid-kunji did u get this working? I am getting the same error.

  • 1 Votes
    5 Posts

    Not particularly... there's no exposure to the testing suite via plugins.

    If you want to test the plugin via eslint, you can run it locally: ./node_modules/.bin/eslint .

  • 0 Votes
    6 Posts



    Plugin = module.exports; var categories = require.main.require('./src/categories'); // init hook Plugin.init = function (data, callback) { var router = data.router; var middleware = data.middleware; // Create route to render the template to. router.get('/example-categories', middleware.buildHeader, renderExampleCategories); router.get('/api/example-categories', renderExampleCategories); function renderExampleCategories(req, res, next) { // Get all the visible categories. categories.getCategoriesByPrivilege('cid:0:children', req.uid, 'find', function(err, categoryData) { if (err) return next(err); // Put the categories in a tree format. categories.flattenCategories([], categoryData); // Send the data to the template. `example-categories.tpl` res.render('example-categories', {categories: categoryData}); }); } };


    <!-- BEGIN categories --> <a href="{config.relative_path}/category/{categories.slug}" itemprop="url">{}</a> <br> <!-- BEGIN categories.children --> - <a href="{config.relative_path}/category/{categories.children.slug}" itemprop="url">{}</a> <br> <!-- END categories.children --> <!-- END categories -->

    Should give you a list like this

  • 1 Votes
    11 Posts

    Okay, no problem. Might even simplify the code a bit to do it this way.