Skip to content

NodeBB Plugins

Discussion regarding NodeBB Plugin development.

1.8k Topics 15.2k Posts
Most Voted Plugins

Subcategories


  • Have a question about building a plugin? Ask here
    440 Topics
    2k Posts
    barisB
    You could use the below custom javascript, it will open the last chat if there is no open chat. $(window).on('action:ajaxify.end', async () => { const { data } = ajaxify; if (data.template.chats && !data.template.roomId && data.rooms.length) { const Chats = await app.require('forum/chats'); Chats.switchChat(data.rooms[0].roomId); } });
  • Need a plugin developed? Ask here!
    223 Topics
    1k Posts
    Silver.meS
    I am willing to pay whatever it takes, $30 max.
  • image over mouse over active links?

    1
    0 Votes
    1 Posts
    350 Views
    DemerzelD
    Hello I would like to display an image over mouse over active links? thx
  • This topic is deleted!

    2
    0 Votes
    2 Posts
    377 Views
  • Category notifications

    1
    0 Votes
    1 Posts
    411 Views
    G
    I'd like to allow for configuring notifications on category level. Is the nodebb-plugin-category-notifications the only option to achieve this? Installing + activation works on my otherwise flawless Nodebb 1.10.1 installation. However hitting Dashboard --> Plugins --> Category Notifications just endlessly shows a spinner. I've filed an issue at https://github.com/NodeBB/nodebb-plugin-category-notifications/issues/9 but received yet no reply. For clarification: Users should receive notifications whenever a new post / reply appears within a given category. Happy to see an other way achieving this.
  • [nodebb-plugin-alignment] and [nodebb-plugin-simple-spoiler]

    1
    1 Votes
    1 Posts
    531 Views
    am1cableA
    here https://www.npmjs.com/package/nodebb-plugin-alignment and https://www.npmjs.com/package/nodebb-plugin-simple-spoiler Text and image alignment in the first one, a simple spoiler that allows you to name them and stack them inside each other in the second. Both built for default composer and super plain so you can style them as you like. same as other plugins - they're for my personal site so no guaranteed support.
  • [nodebb-widget-game-server-query]

    3
    5 Votes
    3 Posts
    1k Views
    yariplusY
    Updated to 1.1.0 Fixes a crash with newer node versions. Added the query protocol to the game dropdown.
  • How to properly change username ?

    4
    0 Votes
    4 Posts
    925 Views
    barisB
    calling ajaxify.refresh() should refresh the page.
  • NodeBB Android App

    79
    11 Votes
    79 Posts
    57k Views
    A
    @Rootzilla be more precise.
  • solr search not working

    1
    0 Votes
    1 Posts
    428 Views
    instkffffI
    Search Plugin installed Solr connection OK Solr Indexing Enabled all checked but when i search error: /api/search SolrError at IncomingMessage.<anonymous> (/home/NodeBB-1.10.1/node_modules/solr-client/lib/solr.js:991:19) at emitNone (events.js:111:20) at IncomingMessage.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1064:12) at _combinedTickCallback (internal/process/next_tick.js:139:11) at process._tickCallback (internal/process/next_tick.js:181:9) Who can help with it, Thanks.
  • How to extend markdown / editor

    9
    0 Votes
    9 Posts
    2k Views
    J
    Hi @John-Cole and @Atayz Take a look here: https://community.nodebb.org/topic/12856/nodebb-plugin-composer-quill-wysiwyg-alternative-to-redactor All the best, JJ.
  • Slack integration

    14
    0 Votes
    14 Posts
    5k Views
    theportablegeekT
    Is the Slack Extended Plugin only one-way (i.e. sends from Nodebb to Slack but not the other way)?
  • nodebb-plugin-slack-extended updated for NodeBB v1.x.x

    2
    2 Votes
    2 Posts
    2k Views
    theportablegeekT
    @pichalite From my limited experience with your plugin the communication with slack is only one way (I.e. Nodebb to Slack.) Is it possible to recieve as well?
  • nodebb-plugin-sso-saml do not working

    1
    0 Votes
    1 Posts
    507 Views
    torresfengT
    nodebb v1.10.1 code: (function(module) { "use strict"; var user = module.parent.require('./user'), meta = module.parent.require('./meta'), db = module.parent.require('../src/database'), passport = module.parent.require('passport'), passportSAML = require('passport-saml').Strategy, fs = module.parent.require('fs'), path = module.parent.require('path'), nconf = module.parent.require('nconf'), async = module.parent.require('async'), winston = require('winston'); var constants = Object.freeze({ 'name': "SAML", 'admin': { 'route': '/plugins/sso-saml', 'icon': 'fa-university' } }); var SAML = {}; var samlObj; if (meta.config['sso:saml:idpentrypoint'] && meta.config['sso:saml:callbackpath']&& meta.config["sso:saml:metadata"] && meta.config["sso:saml:issuer"]) { console.log(nconf.get('url')); samlObj = new passportSAML({ path: meta.config['sso:saml:callbackpath'], entryPoint: meta.config['sso:saml:idpentrypoint'], issuer: meta.config['sso:saml:issuer'], callbackUrl: nconf.get('url') + meta.config['sso:saml:callbackpath'], disableRequestedAuthnContext: true, identifierFormat: null }, function(profile, done) { console.log(profile,'zheli'); var user = { nameID: profile.nameID, nameIDFormat: profile.nameIDFormat, sn: profile['urn:oid:2.5.4.4'], // sn //sn: profile.sn, cn: profile['urn:oid:2.5.4.42'], // givenname //cn: profile.cn, //mail: profile.mail, //eduPersonAffiliation: profile.eduPersonAffiliation, email: profile.mail, //email: profile.email, username: profile['urn:oid:1.3.6.1.4.1.5923.1.1.1.2'], // eduPersonNickname //username: profile.eduPersonNickname }; SAML.login(user,function(err, user) { if (err) { return done(err); } done(null, user); }); } ); } else{ console.log("No config info") console.log(meta.config); } SAML.init = function(params,callback) { // app, middleware, controllers, callback var app = params.router; var middleware = params.middleware; var controllers = params.controllers; function render(req, res, next) { res.render('admin/plugins/sso-saml', {}); } app.get('/admin/plugins/sso-saml', middleware.admin.buildHeader, render); app.get('/api/admin/plugins/sso-saml', render); console.log(456); console.log(samlObj); if (samlObj){ if (meta.config["sso:saml:metadata"]) { app.get(meta.config["sso:saml:metadata"], function(req, res) { console.log(123); if (meta.config["sso:saml:servercrt"]){ var cert = fs.readFileSync(meta.config["sso:saml:servercrt"], 'utf-8'); res.header("Content-Type", "application/xml"); res.send(samlObj.generateServiceProviderMetadata(cert)) } else{ res.send("No servercrt specified. Please enter it at nodebb admin panel."); } }); } app.post(meta.config['sso:saml:callbackpath'], passport.authenticate('saml'), function(req, res, next){ if (meta.config['sso:saml:loginsuccessredirecturl']){ res.redirect(meta.config['sso:saml:loginsuccessredirecturl']); } else{ res.redirect("/"); } } ); if (meta.config['sso:saml:logouturl']) { app.get(meta.config['sso:saml:logouturl'],function(req,res){ if (req.user && parseInt(req.user.uid, 10) > 0) { winston.info('[Auth] Session ' + req.sessionID + ' logout (uid: ' + req.user.uid + ')'); var ws = module.parent.require('./socket.io'); ws.logoutUser(req.user.uid); req.logout(); if (meta.config['sso:saml:logoutredirecturl']){ res.redirect(meta.config['sso:saml:logoutredirecturl']); } else{ res.redirect("/"); } } }); } } callback(); }; SAML.getStrategy = function(strategies, callback) { console.log("filter:auth.init..."); console.log(strategies); if (samlObj){ passport.use(samlObj); strategies.push({ name: 'saml', url: '/auth/saml', callbackURL: meta.config['sso:saml:callbackpath'], icon: constants.admin.icon, scope: '' }); } callback(null, strategies); }; SAML.login = function(userdata, callback) { SAML.getUidBySAMLId(userdata.username, function(err, uid) { if(err) { return callback(err); } if (uid !== null) { // Existing User callback(null, { uid: uid }); } else { console.log(userdata); // New User user.create({ username: userdata.username, email: userdata.email, fullname : userdata.first_name + " " + userdata.last_name }, function(err, uid) { if(err) { return callback(err); } user.setUserField(uid, 'samlid', userdata.username); db.setObjectField('samlid:uid', userdata.username, uid); callback(null, { uid: uid }); }); } }); }; SAML.getUidBySAMLId = function(samlid, callback) { db.getObjectField('samlid:uid', samlid, function(err, uid) { if (err) { return callback(err); } callback(null, uid); }); }; SAML.addMenuItem = function(custom_header, callback) { custom_header.authentication.push({ "route": constants.admin.route, "icon": constants.admin.icon, "name": constants.name }); callback(null, custom_header); }; SAML.deleteUserData = function(uid, callback) { async.waterfall([ async.apply(user.getUserField, uid, 'samlid'), function(idToDelete, next) { db.deleteObjectField('samlid:uid', idToDelete, next); } ], function(err) { if (err) { winston.error('[sso-saml] Could not remove user data for uid ' + uid + '. Error: ' + err); return callback(err); } callback(null, uid); }); }; module.exports = SAML; }(module));
  • Plugin for authenticate users using SAML

    3
    1 Votes
    3 Posts
    2k Views
    torresfengT
    Error 'no configuration information' NodeBB V.1.10.1 I see it has no recent commit. Can it still be used?
  • Integration with Wiki.js?

    3
    0 Votes
    3 Posts
    737 Views
    Giorgio TaveG
  • Charts/training diary

    2
    0 Votes
    2 Posts
    496 Views
    PitaJP
    You can do pretty much anything you want if you're willing to put in the work to make a plugin. Without that, though, no there's no way to configure NodeBB core to do that.
  • my plugins do not update !?!

    Solved
    3
    0 Votes
    3 Posts
    638 Views
    The WormsT
    ok, tks
  • This topic is deleted!

    1
    0 Votes
    1 Posts
    26 Views
  • [nodebb-rewards-essentials] "last logged in" value

    1
    0 Votes
    1 Posts
    556 Views
    Alex GalaxA
    what's the value of the "last logged in" option? How do I query that in the settings?
  • async function does not work in a plugin

    7
    0 Votes
    7 Posts
    1k Views
    JenklerJ
    Works great in 8.x now
  • NodeBB referral system plugin

    13
    2 Votes
    13 Posts
    5k Views
    surikmeetrS
    @yariplus You mean user-specific invite links? I'm aware, and it works on 1.10 (though the links are incorrect if nodebb is in a subfolder, a problem many plugins have). But I meant specifically what you referenced in issue #52 on github: adding a unique code to the invitation link so it's not possible to guess it.