Plugin possible?

Hey all,

How possible would it be to build a SSO plugin for Frill.co?

Here’s the documentation: SSO implementation - Frill Help Docs which seems relatively straight forward. It takes 3 pieces of into about the user (email, id & name) and encrypts it to make a JWT which is sent as part of the redirect back to Frill.

Am interested in seeing something like this put together if possible.

Seems this might be possible with a server action since that allows you to use node packages.

From the docs

In bubble

You can add a param to pass in a user, that will let you access those three fields, which you can then process with a bit of javascript.

That action would then return the entire URL including the token, and you can just have a Open external page action in the next step of your action that uses that full url with the token.

That might work, not 100% sure if the Open external page works but there is probably another way for that last part.

Hi, have you implemented this one?

Yep! @Kayami 's suggestion worked perfectly! He’s a genius.

I’ve managed to do it. Just curious, does this also happen to your app? I have the SSO setup on a widget. The notification badge is always showing whenever you change device even though you have read the announcement on another device with your account?

Hey all,

I’ve been trying to replicate this same thing. This is my first time building a Server Action plugin, and I have limited knowledge after watching @Kayami do it on Buildcamp.

This is what I have so far; any guidance would be great! Thanks!

[Redacted image because it was revealing the FrillSSOKey]

@johnny This all looks pretty good… are you getting an error? Or what exactly is the next part that you are presently confused about?

1 Like

Ah yes, this is the error I’m getting:

Screenshot 2022-12-12 at 13.02.44

I see now the issue. You are trying to actually return the token from the async call so what you want to do is this:

let token = context.async(...)

You want to change your callback to look like this:

callback(null, frillUserToken)

Then you want your return on the next line to look like this:

return { redirect: token }

That should get you where you want to be (fingers crossed since I didn’t test your code).

Also, just a minor note in case you have questions down the line… it is much easier to help with plugin issues if you actually copy/paste the code into the post because then we can check code on our end before presenting it back to you.

1 Like

Gotcha. Pasting the code below:

function(properties, context) {
    var jwt = require('jsonwebtoken');
    var FrillSSOKey = 'FrillSSOKey';
    var userData = { 
      email: properties.user.email,
      id: properties.user.id,
      name: properties.user.name,
    };
    
    let token = context.async(async(callback) => {
    	var frillUserToken = jwt.sign(userData, FrillSSOKey, {algorithm: 'HS256'});
        callback(null, frillUserToken);
        return { redirect: token }
  }); 

}

Is this the implementation you meant?

By the way you could also use Canny, their integration is much simpler!

1 Like

Gotcha, I checked them out a while back (I’m using this for my nonprofit), and it was way overbudget, but their integration looks similar? How to Implement Single Sign-On | Canny

We used them for non-profit as well and we got a 100% discount :pleading_face:
So you might not find a cheaper option!

They allow API connexion as well as SSO login.

1 Like
let token = context.async(async(callback) => {
	var frillUserToken = jwt.sign(userData, FrillSSOKey, {algorithm: 'HS256'});
    callback(null, frillUserToken); }); 

return { redirect: token } }

Your return statement needs to be outside the callback (the last thing in your code block should be the return statement, Otherwise yes, everything else looks correct to me.

1 Like

Ok lol i might need to have a conversation with them again :rofl:

1 Like

Tip: make sure the package size is not over 50mb. If it is, it won’t work

2 Likes

Update: I’ve just finally circled back on this, and it seems that the SSO token being generated isn’t invalid. Any ideas?

Screenshot 2023-01-11 at 18.42.46

The code I have so far for run_server

function(properties, context) {

    var jwt = require('jsonwebtoken');
    var FrillSSOKey = 'FRILL_SSO_CODE';
    var userData = { 
      email: properties.user.email,
      id: properties.user.id,
      name: properties.user.name,
    };
    
    let token = context.async(async(callback) => {
        var frillUserToken = jwt.sign(userData, FrillSSOKey, {algorithm: 'HS256'});
        callback(null, frillUserToken);
    }); 
    
    return { redirect: token }
}

@johnny the documentation is a bit limited so I am shooting in the dark, but try adding an await before the jwt.sign() so:

var frillUserToken = await jwt.sign(userData, FrillSSOKey, {algorithm: 'HS256'});

There is no need to use context.async because jwt.sign can be used synchronously.
The code in the docs is all you need. You just need to pass the fill sso key dynamically from the plugin keys:

var jwt = require('jsonwebtoken');
var FrillSSOKey = context.keys.FILL_SSO_KEY';
var userData = { 
  email: 'email',
  id: 'id',
  name: 'name',
};
var token = jwt.sign(userData, FrillSSOKey, {algorithm: 'HS256'});
    
return {token}

Of course you need to add FILL_SSO_KEY as a private key in the “additional keys” sections of the “shared” tab.

2 Likes

Thanks for your help @dorilama @bubble.trouble,

Unfortunately, I’m still getting the same error. Updated code below:

function(properties, context) {
    var jwt = require('jsonwebtoken');
    var FrillSSOKey = context.keys["Frill SSO Token"];
    var userData = { 
      email: properties.user.email,
      id: properties.user.id,
      name: properties.user.name,
    };
    var token = jwt.sign(userData, FrillSSOKey, {algorithm: 'HS256'});

    return {token}
}

var FrillSSOKey = context.keys.FILL_SSO_KEY; wasn’t working for me; it seems like it’s used as a list, so var FrillSSOKey = context.keys["Frill SSO Token"]; worked. The error I’m getting now is from Frill, the same one from earlier:

Screenshot 2023-01-12 at 11.01.25

Any ideas? Thanks!